um_data_structures.c

Go to the documentation of this file.
00001 /*************************************************** */
00002 /* Rule Set Based Access Control                     */
00003 /* Implementation of User Management data structures */
00004 /* Author and (c) 1999-2005: Amon Ott <ao@rsbac.org> */
00005 /*                                                   */
00006 /* Last modified: 04/Feb/2005                        */
00007 /*************************************************** */
00008 
00009 #include <linux/types.h>
00010 #include <linux/sched.h>
00011 #include <linux/mm.h>
00012 #include <linux/init.h>
00013 #include <linux/random.h>
00014 #include <asm/uaccess.h>
00015 #include <rsbac/types.h>
00016 #include <rsbac/aci_data_structures.h>
00017 #include <rsbac/um_types.h>
00018 #include <rsbac/error.h>
00019 #include <rsbac/helpers.h>
00020 #include <rsbac/adf.h>
00021 #include <rsbac/aci.h>
00022 #include <rsbac/um.h>
00023 #include <rsbac/lists.h>
00024 #include <rsbac/proc_fs.h>
00025 #include <rsbac/rkmem.h>
00026 #include <rsbac/getname.h>
00027 #include <linux/string.h>
00028 #include <linux/smp_lock.h>
00029 #include <linux/delay.h>
00030 #ifdef CONFIG_RSBAC_UM_DIGEST
00031 #include <linux/crypto.h>
00032 #include <asm/scatterlist.h>
00033 #endif
00034 /************************************************************************** */
00035 /*                          Global Variables                                */
00036 /************************************************************************** */
00037 
00038 static rsbac_list_handle_t user_handle[RSBAC_UM_NR_USER_LISTS];
00039 static rsbac_list_handle_t group_handle[RSBAC_UM_NR_GROUP_LISTS];
00040 
00041 #define EXTRA_ROOM 20
00042 
00043 /**************************************************/
00044 /*       Declarations of external functions       */
00045 /**************************************************/
00046 
00047 /**************************************************/
00048 /*       Declarations of internal functions       */
00049 /**************************************************/
00050 
00051 /************************************************* */
00052 /*               Internal Help functions           */
00053 /************************************************* */
00054 
00055 static inline int user_hash(rsbac_uid_t user)
00056   {
00057     return(user % RSBAC_UM_NR_USER_LISTS);
00058   }
00059 
00060 static inline int group_hash(rsbac_gid_t group)
00061   {
00062     return(group % RSBAC_UM_NR_GROUP_LISTS);
00063   }
00064 
00065 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
00066 #if 0
00067 static int
00068 um_users_proc_info(char *buffer, char **start, off_t offset, int length)
00069 {
00070   int len = 0;
00071   off_t pos   = 0;
00072   off_t begin = 0;
00073   struct rsbac_mac_device_list_item_t   * device_p;
00074   u_long dflags;
00075 
00076   if (!rsbac_is_initialized()) return (-ENOSYS);
00077 
00078   len += sprintf(buffer, "%u RSBAC MAC Devices\n-------------------\n",
00079                  device_list_head.count);
00080 
00081   /* wait for read access to device_list_head */
00082   rsbac_read_lock(&device_list_head.lock, &dflags);
00083   /* OK, go on */
00084   for (device_p = device_list_head.head; device_p; device_p = device_p->next)
00085     {
00086       len += sprintf(buffer + len, "%02u:%02u with mount_count = %u\n",
00087                      RSBAC_MAJOR(device_p->id), RSBAC_MINOR(device_p->id),
00088                      device_p->mount_count);
00089       pos = begin + len;
00090       if (pos < offset)
00091         {
00092           len = 0;
00093           begin = pos;
00094         }
00095       if (pos > offset+length)
00096         break;
00097     }
00098   
00099   /* free access to device_list_head */
00100   rsbac_read_unlock(&device_list_head.lock, &dflags);
00101 
00102   *start = buffer + (offset - begin);
00103   len -= (offset - begin);
00104   
00105   if (len > length)
00106     len = length;
00107   return len;
00108 }
00109 #endif /* 0 */
00110 
00111 static int
00112 stats_um_proc_info(char *buffer, char **start, off_t offset, int length)
00113   {
00114     u_int len = 0;
00115     off_t pos   = 0;
00116     off_t begin = 0;
00117 
00118     u_long user_count = 0;
00119     u_long group_count = 0;
00120     u_long member_count = 0;
00121     int i;
00122 
00123     union rsbac_target_id_t       rsbac_target_id;
00124     union rsbac_attribute_value_t rsbac_attribute_value;
00125 
00126     if (!rsbac_is_initialized())
00127       {
00128         printk(KERN_WARNING "stats_um_proc_info(): RSBAC not initialized\n");
00129         return(-RSBAC_ENOTINITIALIZED);
00130       }
00131 #ifdef CONFIG_RSBAC_DEBUG
00132     if (rsbac_debug_aef_um)
00133       {
00134 #ifdef CONFIG_RSBAC_RMSG
00135         rsbac_printk(KERN_DEBUG "stats_um_proc_info(): calling ADF\n");
00136 #endif
00137 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00138         if (!rsbac_nosyslog)
00139 #endif
00140         printk(KERN_DEBUG "stats_um_proc_info(): calling ADF\n");
00141       }
00142 #endif
00143     rsbac_target_id.scd = ST_rsbac;
00144     rsbac_attribute_value.dummy = 0;
00145     if (!rsbac_adf_request(R_GET_STATUS_DATA,
00146                            current->pid,
00147                            T_SCD,
00148                            rsbac_target_id,
00149                            A_none,
00150                            rsbac_attribute_value))
00151       {
00152         return -EPERM;
00153       }
00154 
00155     for(i=0; i < RSBAC_UM_NR_USER_LISTS; i++)
00156       {
00157         user_count += rsbac_list_lol_count(user_handle[i]);
00158         member_count += rsbac_list_lol_all_subcount(user_handle[i]);
00159       }
00160     for(i=0; i < RSBAC_UM_NR_GROUP_LISTS; i++)
00161       {
00162         group_count += rsbac_list_count(group_handle[i]);
00163       }
00164 
00165     len += sprintf(buffer, "UM Status\n---------\n");
00166 
00167     len += sprintf(buffer + len, "%lu user items with sum of %lu group memberships, %lu group items\n",
00168                    user_count,
00169                    member_count,
00170                    group_count);
00171     pos = begin + len;
00172     if (pos < offset)
00173       {
00174         len = 0;
00175         begin = pos;
00176       }
00177     *start = buffer + (offset - begin);
00178     len -= (offset - begin);
00179   
00180     if (len > length)
00181       len = length;
00182     return len;
00183   }
00184 
00185 #endif /* CONFIG_PROC_FS && CONFIG_RSBAC_PROC */
00186 
00187 static int name_compare(void * data1, void * data2)
00188   {
00189     struct rsbac_um_user_entry_t * entry_p = data1;
00190     char * name = data2;
00191 
00192     if(!entry_p || !name)
00193       return 1;
00194 
00195     return strcmp(entry_p->name,name);
00196   }
00197 
00198 static int group_name_compare(void * data1, void * data2)
00199   {
00200     struct rsbac_um_group_entry_t * entry_p = data1;
00201     char * name = data2;
00202 
00203     if(!entry_p || !name)
00204       return 1;
00205 
00206     return strcmp(entry_p->name,name);
00207   }
00208 
00209 /************************************************* */
00210 /*               Init functions                    */
00211 /************************************************* */
00212 
00213 /* All functions return 0, if no error occurred, and a negative error code  */
00214 /* otherwise. The error codes are defined in rsbac/error.h.                 */
00215 
00216 /************************************************************************** */
00217 /* Initialization of all MAC data structures. After this call, all MAC    */
00218 /* data is kept in memory for performance reasons, but is written to disk   */
00219 /* on every change. */
00220 
00221 /* Because there can be no access to aci data structures before init,       */
00222 /* rsbac_init_mac() will initialize all rw-spinlocks to unlocked.          */
00223 
00224 #ifdef CONFIG_RSBAC_INIT_DELAY
00225 int rsbac_init_um(void)
00226 #else
00227 int __init rsbac_init_um(void)
00228 #endif
00229   {
00230     int  err = 0;
00231     struct proc_dir_entry * tmp_entry_p;
00232     struct rsbac_list_info_t     * list_info_p;
00233     struct rsbac_list_lol_info_t * lol_info_p;
00234     char name[20];
00235     int i;
00236 
00237     if (rsbac_is_initialized())
00238       {
00239 #ifdef CONFIG_RSBAC_RMSG
00240         rsbac_printk(KERN_WARNING "rsbac_init_um(): RSBAC already initialized\n");
00241 #endif
00242 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00243         if (!rsbac_nosyslog)
00244 #endif
00245         printk(KERN_WARNING "rsbac_init_um(): RSBAC already initialized\n");
00246         return(-RSBAC_EREINIT);
00247       }
00248 
00249     /* set rw-spinlocks to unlocked status and init data structures */
00250 #ifdef CONFIG_RSBAC_RMSG
00251     rsbac_printk(KERN_INFO "rsbac_init_um(): Initializing RSBAC: User Management subsystem\n");
00252 #endif
00253 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00254     if (!rsbac_nosyslog)
00255 #endif
00256     printk(KERN_INFO "rsbac_init_um(): Initializing RSBAC: User Management subsystem\n");
00257 
00258     list_info_p = kmalloc(sizeof(*list_info_p), GFP_KERNEL);
00259     if(!list_info_p)
00260       {
00261         return -ENOMEM;
00262       }
00263     lol_info_p = kmalloc(sizeof(*lol_info_p), GFP_KERNEL);
00264     if(!lol_info_p)
00265       {
00266         kfree(list_info_p);
00267         return -ENOMEM;
00268       }
00269 
00270     lol_info_p->version = RSBAC_UM_USER_LIST_VERSION;
00271     lol_info_p->key = RSBAC_UM_USER_LIST_KEY;
00272     lol_info_p->desc_size = sizeof(rsbac_uid_t);
00273     lol_info_p->data_size = sizeof(struct rsbac_um_user_entry_t);
00274     lol_info_p->subdesc_size = sizeof(rsbac_gid_t);
00275     lol_info_p->subdata_size = 0;
00276     lol_info_p->max_age = 0;
00277     for(i=0; i < RSBAC_UM_NR_USER_LISTS; i++)
00278       {
00279         sprintf(name, "%s%u", RSBAC_UM_USER_LIST_NAME, i);
00280         err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00281                                   &user_handle[i],
00282                                   lol_info_p,
00283                                   #ifdef CONFIG_RSBAC_DEV_USER_BACKUP
00284                                   RSBAC_LIST_BACKUP |
00285                                   #endif
00286                                   RSBAC_LIST_PERSIST,
00287                                   NULL,
00288                                   NULL,
00289                                   NULL,
00290                                   NULL,
00291                                   NULL,
00292                                   NULL,
00293                                   name,
00294                                   RSBAC_AUTO_DEV);
00295         if(err)
00296           {
00297             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00298 
00299             if(tmp)
00300               {
00301 #ifdef CONFIG_RSBAC_RMSG
00302                 rsbac_printk(KERN_WARNING
00303                        "rsbac_init_um(): Registering user list of lists %u failed with error %s\n",
00304                        i,
00305                        get_error_name(tmp, err));
00306 #endif
00307 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00308                 if (!rsbac_nosyslog)
00309 #endif
00310                 printk(KERN_WARNING
00311                        "rsbac_init_um(): Registering user list of lists %u failed with error %s\n",
00312                        i,
00313                        get_error_name(tmp, err));
00314               }
00315           }
00316       }
00317 
00318     list_info_p->version = RSBAC_UM_GROUP_LIST_VERSION;
00319     list_info_p->key = RSBAC_UM_GROUP_LIST_KEY;
00320     list_info_p->desc_size = sizeof(rsbac_gid_t);
00321     list_info_p->data_size = sizeof(struct rsbac_um_group_entry_t);
00322     list_info_p->max_age = 0;
00323     for(i=0; i < RSBAC_UM_NR_GROUP_LISTS; i++)
00324       {
00325         sprintf(name, "%s%u", RSBAC_UM_GROUP_LIST_NAME, i);
00326         err = rsbac_list_register(RSBAC_LIST_VERSION,
00327                                   &group_handle[i],
00328                                   list_info_p,
00329                                   #ifdef CONFIG_RSBAC_DEV_USER_BACKUP
00330                                   RSBAC_LIST_BACKUP |
00331                                   #endif
00332                                   RSBAC_LIST_PERSIST,
00333                                   NULL,
00334                                   NULL,
00335                                   NULL,
00336                                   name,
00337                                   RSBAC_AUTO_DEV);
00338         if(err)
00339           {
00340             char * tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00341 
00342             if(tmp)
00343               {
00344 #ifdef CONFIG_RSBAC_RMSG
00345                 rsbac_printk(KERN_WARNING
00346                        "rsbac_init_um(): Registering group list %u failed with error %s\n",
00347                        i,
00348                        get_error_name(tmp, err));
00349 #endif
00350 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00351                 if (!rsbac_nosyslog)
00352 #endif
00353                 printk(KERN_WARNING
00354                        "rsbac_init_um(): Registering group list %u failed with error %s\n",
00355                        i,
00356                        get_error_name(tmp, err));
00357               }
00358           }
00359       }
00360 
00361     #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
00362     tmp_entry_p = create_proc_entry("stats_um",
00363                                     S_IFREG | S_IRUGO,
00364                                     proc_rsbac_root_p);
00365     if(tmp_entry_p)
00366       {
00367         tmp_entry_p->get_info = stats_um_proc_info;
00368       }
00369     #endif
00370 
00371 #ifdef CONFIG_RSBAC_DEBUG
00372     if (rsbac_debug_ds_um)
00373       {
00374 #ifdef CONFIG_RSBAC_RMSG
00375         rsbac_printk(KERN_DEBUG "rsbac_init_um(): Ready.\n");
00376 #endif
00377 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00378         if (!rsbac_nosyslog)
00379 #endif
00380         printk(KERN_DEBUG "rsbac_init_um(): Ready.\n");
00381       }
00382 #endif
00383 
00384     kfree(list_info_p);
00385     kfree(lol_info_p);
00386     return(err);
00387   };
00388 
00389 /***************************************************/
00390 /* We also need some status information...         */
00391 
00392 int rsbac_stats_um(void)
00393   {
00394     u_long user_count = 0;
00395     u_long group_count = 0;
00396     u_long member_count = 0;
00397     int i;
00398   
00399     union rsbac_target_id_t       rsbac_target_id;
00400     union rsbac_attribute_value_t rsbac_attribute_value;
00401 
00402     if (!rsbac_is_initialized())
00403       {
00404 #ifdef CONFIG_RSBAC_RMSG
00405         rsbac_printk(KERN_WARNING "rsbac_stats_um(): RSBAC not initialized\n");
00406 #endif
00407 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00408         if (!rsbac_nosyslog)
00409 #endif
00410         printk(KERN_WARNING "rsbac_stats_um(): RSBAC not initialized\n");
00411         return(-RSBAC_ENOTINITIALIZED);
00412       }
00413 #ifdef CONFIG_RSBAC_DEBUG
00414     if (rsbac_debug_aef_um)
00415       {
00416 #ifdef CONFIG_RSBAC_RMSG
00417         rsbac_printk(KERN_DEBUG "rsbac_stats_um(): calling ADF\n");
00418 #endif
00419 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00420         if (!rsbac_nosyslog)
00421 #endif
00422         printk(KERN_DEBUG "rsbac_stats_um(): calling ADF\n");
00423       }
00424 #endif
00425     rsbac_target_id.scd = ST_rsbac;
00426     rsbac_attribute_value.dummy = 0;
00427     if (!rsbac_adf_request(R_GET_STATUS_DATA,
00428                            current->pid,
00429                            T_SCD,
00430                            rsbac_target_id,
00431                            A_none,
00432                            rsbac_attribute_value))
00433       {
00434         return -EPERM;
00435       }
00436 
00437     for(i=0; i < RSBAC_UM_NR_USER_LISTS; i++)
00438       {
00439         user_count += rsbac_list_lol_count(user_handle[i]);
00440         member_count += rsbac_list_lol_all_subcount(user_handle[i]);
00441       }
00442     for(i=0; i < RSBAC_UM_NR_GROUP_LISTS; i++)
00443       {
00444         group_count += rsbac_list_count(group_handle[i]);
00445       }
00446     printk(KERN_INFO "UM Status\n---------\n");
00447 
00448     printk(KERN_INFO "%lu user items with sum of %lu group memberships, %lu group items\n",
00449                    user_count,
00450                    member_count,
00451                    group_count);
00452     return(0);
00453   };
00454 
00455 /************************************************* */
00456 /*               Access functions                  */
00457 /************************************************* */
00458 
00459 /* Trying to access a never created or removed user entry returns an error! */
00460 #ifndef offset_in_page
00461 #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
00462 #endif
00463 
00464 static inline void new_salt(__u32 * salt_p)
00465   {
00466     *salt_p = 0;
00467     while(!*salt_p)
00468       get_random_bytes(salt_p, sizeof(*salt_p));
00469   }
00470 
00471 int rsbac_um_hash(char * pass, __u32 salt)
00472   {
00473 #ifdef CONFIG_RSBAC_UM_DIGEST
00474     char * buffer;
00475     struct scatterlist sg[1];
00476     struct crypto_tfm *tfm;
00477     u_int len;
00478     u_int plen;
00479 
00480     plen = strlen(pass);
00481     len = rsbac_max(plen + sizeof(salt), RSBAC_UM_PASS_LEN);
00482     buffer = rsbac_kmalloc(len);
00483     if(!buffer)
00484       return -RSBAC_ENOMEM;
00485 
00486     if(!crypto_alg_available("sha1",0))
00487       {
00488 #ifdef CONFIG_RSBAC_RMSG
00489         rsbac_printk(KERN_WARNING
00490                      "rsbac_um_hash(): User management configured for crypto API with SHA1, but SHA1 is not available!\n");
00491 #endif
00492 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00493         if (!rsbac_nosyslog)
00494 #endif
00495         printk(KERN_WARNING
00496                "rsbac_um_hash(): User management configured for crypto API with SHA1, but SHA1 is not available!\n");
00497         rsbac_kfree(buffer);
00498         return -RSBAC_ENOTFOUND;
00499       }
00500     tfm = crypto_alloc_tfm("sha1", 0);
00501     if(!tfm)
00502       {
00503 #ifdef CONFIG_RSBAC_RMSG
00504         rsbac_printk(KERN_WARNING
00505                      "rsbac_um_hash(): Could not allocate tfm for SHA1!\n");
00506 #endif
00507 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00508         if (!rsbac_nosyslog)
00509 #endif
00510         printk(KERN_WARNING
00511                "rsbac_um_hash(): Could not allocate tfm for SHA1!\n");
00512         rsbac_kfree(buffer);
00513         return -RSBAC_ENOMEM;
00514       }
00515     memset(buffer, 0, len);
00516     memcpy(buffer, &salt, sizeof(salt));
00517     strcpy(buffer + sizeof(salt), pass);
00518     sg[0].page = virt_to_page(buffer);
00519     sg[0].offset = offset_in_page(buffer);
00520     sg[0].length = plen + sizeof(salt);
00521     
00522     crypto_digest_init(tfm);
00523     crypto_digest_update(tfm, sg, 1);
00524     crypto_digest_final(tfm, buffer);
00525     crypto_free_tfm(tfm);
00526 
00527     memcpy(pass, buffer, RSBAC_UM_PASS_LEN);
00528     rsbac_kfree(buffer);
00529     return 0;
00530 #else
00531     /* no crypto: just zero rest of string to allow comparizon */
00532     u_int len;
00533 
00534     len=strlen(pass);
00535     if(len < RSBAC_UM_PASS_LEN)
00536       memset(pass + len, 0, RSBAC_UM_PASS_LEN - len);
00537     return 0;
00538 #endif
00539   }
00540 
00541 int rsbac_um_get_uid(
00542   rsbac_list_ta_number_t ta_number,
00543   char * name,
00544   rsbac_uid_t * uid_p)
00545   {
00546     int i;
00547 
00548     if(!name || !uid_p)
00549       return -RSBAC_EINVALIDPOINTER;
00550     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
00551       {
00552         if(!rsbac_ta_list_lol_get_desc(ta_number,
00553                                        user_handle[i],
00554                                        uid_p,
00555                                        name,
00556                                        name_compare))
00557           return 0;
00558       }
00559     return -RSBAC_ENOTFOUND;
00560   }
00561 
00562 int rsbac_um_get_gid(
00563   rsbac_list_ta_number_t ta_number,
00564   char * name,
00565   rsbac_gid_t * gid_p)
00566   {
00567     int i;
00568 
00569     if(!name || !gid_p)
00570       return -RSBAC_EINVALIDPOINTER;
00571     for(i=0; i<RSBAC_UM_NR_GROUP_LISTS; i++)
00572       {
00573         if(!rsbac_ta_list_get_desc(ta_number,
00574                                    group_handle[i],
00575                                    gid_p,
00576                                    name,
00577                                    group_name_compare))
00578           return 0;
00579       }
00580     return -RSBAC_ENOTFOUND;
00581   }
00582 
00583 int rsbac_um_add_user(
00584   rsbac_list_ta_number_t ta_number,
00585   rsbac_uid_t user,
00586   struct rsbac_um_user_entry_t * entry_p,
00587   char * pass,
00588   rsbac_time_t ttl)
00589   {
00590     int err;
00591 
00592     if (!rsbac_is_initialized())
00593       {
00594         printk(KERN_WARNING "rsbac_um_add_user(): RSBAC not initialized\n");
00595         return(-RSBAC_ENOTINITIALIZED);
00596       }
00597     if(!entry_p)
00598       return -RSBAC_EINVALIDPOINTER;
00599     if(!rsbac_um_get_uid(ta_number, entry_p->name, &user))
00600       return -RSBAC_EEXISTS;
00601 #ifdef CONFIG_RSBAC_UM_EXCL
00602     if(!rsbac_um_no_excl && !rsbac_ta_list_exist(ta_number, group_handle[group_hash(entry_p->group)], &entry_p->group))
00603       {
00604 #ifdef CONFIG_RSBAC_RMSG
00605         rsbac_printk(KERN_INFO
00606                      "rsbac_um_add_user(): gid %u not known to RSBAC User Management!\n",
00607                      entry_p->group);
00608 #endif
00609 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00610         if (!rsbac_nosyslog)
00611 #endif
00612           printk(KERN_INFO
00613                  "rsbac_um_add_user(): gid %u not known to RSBAC User Management!\n",
00614                  entry_p->group);
00615         return -RSBAC_EINVALIDVALUE;
00616       }
00617 #endif
00618     if(user == RSBAC_NO_USER)
00619       {
00620         user = CONFIG_RSBAC_UM_USER_MIN;
00621         while(rsbac_ta_list_lol_exist(ta_number, user_handle[user_hash(user)], &user))
00622           user++;
00623       }
00624     else
00625       if(rsbac_ta_list_lol_exist(ta_number, user_handle[user_hash(user)], &user))
00626         return -RSBAC_EEXISTS;
00627 #ifdef CONFIG_RSBAC_DEBUG
00628       if (rsbac_debug_aef_um)
00629         {
00630 #ifdef CONFIG_RSBAC_RMSG
00631           rsbac_printk(KERN_DEBUG "rsbac_um_add_user(): adding user %u\n",
00632                        user);
00633 #endif
00634 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00635           if (!rsbac_nosyslog)
00636 #endif
00637           printk(KERN_DEBUG "rsbac_um_add_user(): adding user %u\n",
00638                  user);
00639       }
00640 #endif
00641     if(pass)
00642       {
00643         __u32 salt;
00644 
00645         new_salt(&salt);
00646         err = rsbac_um_hash(pass, salt);
00647         if(err)
00648           return err;
00649         memcpy(entry_p->pass, &salt, sizeof(salt));
00650         memcpy(entry_p->pass + sizeof(salt), pass, RSBAC_UM_PASS_LEN - sizeof(salt));
00651       }
00652     else
00653       memset(entry_p->pass, 0, RSBAC_UM_PASS_LEN);
00654     return rsbac_ta_list_lol_add_ttl(ta_number, user_handle[user_hash(user)],
00655                                      ttl, &user, entry_p);
00656   }
00657 
00658 int rsbac_um_add_group(
00659   rsbac_list_ta_number_t ta_number,
00660   rsbac_gid_t group,
00661   struct rsbac_um_group_entry_t * entry_p,
00662   char * pass,
00663   rsbac_time_t ttl)
00664   {
00665     int err;
00666 
00667     if (!rsbac_is_initialized())
00668       {
00669         printk(KERN_WARNING "rsbac_um_add_group(): RSBAC not initialized\n");
00670         return(-RSBAC_ENOTINITIALIZED);
00671       }
00672     if(!entry_p)
00673       return -RSBAC_EINVALIDPOINTER;
00674     if(!rsbac_um_get_gid(ta_number, entry_p->name, &group))
00675       return -RSBAC_EEXISTS;
00676     if(group == RSBAC_NO_USER)
00677       {
00678         group = CONFIG_RSBAC_UM_GROUP_MIN;
00679         while(rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
00680           group++;
00681       }
00682     else
00683       if(rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
00684         return -RSBAC_EEXISTS;
00685 #ifdef CONFIG_RSBAC_DEBUG
00686       if (rsbac_debug_aef_um)
00687         {
00688 #ifdef CONFIG_RSBAC_RMSG
00689           rsbac_printk(KERN_DEBUG "rsbac_um_add_group(): adding group %u\n",
00690                        group);
00691 #endif
00692 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00693           if (!rsbac_nosyslog)
00694 #endif
00695           printk(KERN_DEBUG "rsbac_um_add_group(): adding group %u\n",
00696                  group);
00697       }
00698 #endif
00699     if(pass)
00700       {
00701         __u32 salt;
00702 
00703         new_salt(&salt);
00704         err = rsbac_um_hash(pass, salt);
00705         if(err)
00706           return err;
00707         memcpy(entry_p->pass, &salt, sizeof(salt));
00708         memcpy(entry_p->pass + sizeof(salt), pass, RSBAC_UM_PASS_LEN - sizeof(salt));
00709       }
00710     else
00711       memset(entry_p->pass, 0, RSBAC_UM_PASS_LEN);
00712     return rsbac_ta_list_add_ttl(ta_number, group_handle[group_hash(group)], ttl, &group, entry_p);
00713   }
00714 
00715 int rsbac_um_add_gm(
00716   rsbac_list_ta_number_t ta_number,
00717   rsbac_uid_t user,
00718   rsbac_gid_t group,
00719   rsbac_time_t ttl)
00720   {
00721     if (!rsbac_is_initialized())
00722       {
00723         printk(KERN_WARNING "rsbac_um_add_gm(): RSBAC not initialized\n");
00724         return(-RSBAC_ENOTINITIALIZED);
00725       }
00726 #ifdef CONFIG_RSBAC_UM_EXCL
00727     if(!rsbac_um_no_excl)
00728       {
00729         if(!rsbac_ta_list_exist(ta_number, user_handle[user_hash(user)], &user))
00730           {
00731 #ifdef CONFIG_RSBAC_RMSG
00732             rsbac_printk(KERN_INFO
00733                          "rsbac_um_add_gm(): uid %u not known to RSBAC User Management!\n",
00734                          user);
00735 #endif
00736 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00737             if (!rsbac_nosyslog)
00738 #endif
00739               printk(KERN_INFO
00740                      "rsbac_um_add_gm(): uid %u not known to RSBAC User Management!\n",
00741                      user);
00742             return -RSBAC_ENOTFOUND;
00743           }
00744         if(!rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
00745           {
00746 #ifdef CONFIG_RSBAC_RMSG
00747             rsbac_printk(KERN_INFO
00748                          "rsbac_um_add_gm(): gid %u not known to RSBAC User Management!\n",
00749                          group);
00750 #endif
00751 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00752             if (!rsbac_nosyslog)
00753 #endif
00754               printk(KERN_INFO
00755                      "rsbac_um_add_gm(): gid %u not known to RSBAC User Management!\n",
00756                      group);
00757             return -RSBAC_ENOTFOUND;
00758           }
00759       }
00760 #endif
00761 #ifdef CONFIG_RSBAC_DEBUG
00762       if (rsbac_debug_aef_um)
00763         {
00764 #ifdef CONFIG_RSBAC_RMSG
00765           rsbac_printk(KERN_DEBUG "rsbac_um_add_gm(): adding user %u group %u\n",
00766                        user,
00767                        group);
00768 #endif
00769 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00770           if (!rsbac_nosyslog)
00771 #endif
00772           printk(KERN_DEBUG "rsbac_um_add_gm(): adding user %u group %u\n",
00773                  user,
00774                  group);
00775       }
00776 #endif
00777     return rsbac_ta_list_lol_subadd_ttl(ta_number, user_handle[user_hash(user)],
00778                                         ttl, &user, &group, NULL);
00779   }
00780 
00781 int rsbac_um_mod_user(
00782   rsbac_list_ta_number_t ta_number,
00783   rsbac_uid_t user,
00784   enum rsbac_um_mod_t mod,
00785   union rsbac_um_mod_data_t * data_p)
00786   {
00787     int err;
00788     struct rsbac_um_user_entry_t * entry_p;
00789 
00790     if (!rsbac_is_initialized())
00791       {
00792         printk(KERN_WARNING "rsbac_um_mod_user(): RSBAC not initialized\n");
00793         return(-RSBAC_ENOTINITIALIZED);
00794       }
00795     if(   !data_p
00796        && (mod != UM_pass)
00797       )
00798       return -RSBAC_EINVALIDPOINTER;
00799     if(!rsbac_ta_list_lol_exist(ta_number, user_handle[user_hash(user)], &user))
00800       return -RSBAC_ENOTFOUND;
00801 
00802     entry_p = rsbac_kmalloc(sizeof(*entry_p));
00803     if(!entry_p)
00804       return -RSBAC_ENOMEM;
00805     err = rsbac_ta_list_lol_get_data_ttl(ta_number, user_handle[user_hash(user)],
00806                                          NULL, &user, entry_p);
00807     if(err)
00808       {
00809         rsbac_kfree(entry_p);
00810         return err;
00811       }
00812 #ifdef CONFIG_RSBAC_DEBUG
00813       if (rsbac_debug_aef_um)
00814         {
00815 #ifdef CONFIG_RSBAC_RMSG
00816           rsbac_printk(KERN_DEBUG "rsbac_um_mod_user(): modifying user %u\n",
00817                        user);
00818 #endif
00819 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00820           if (!rsbac_nosyslog)
00821 #endif
00822           printk(KERN_DEBUG "rsbac_um_mod_user(): modifying user %u\n",
00823                  user);
00824       }
00825 #endif
00826     switch(mod)
00827       {
00828         case UM_name:
00829           {
00830             rsbac_uid_t tmp_user;
00831 
00832             if(   !rsbac_um_get_uid(ta_number, data_p->string, &tmp_user)
00833                && (tmp_user != user)
00834               )
00835               return -RSBAC_EEXISTS;
00836             strncpy(entry_p->name, data_p->string, RSBAC_UM_NAME_LEN);
00837             entry_p->name[RSBAC_UM_NAME_LEN - 1] = 0;
00838           }
00839           break;
00840 
00841         case UM_pass:
00842           if(data_p)
00843             {
00844               __u32 salt;
00845 
00846               new_salt(&salt);
00847               err = rsbac_um_hash(data_p->string, salt);
00848               if(err)
00849                 {
00850                   rsbac_kfree(entry_p);
00851                   return err;
00852                 }
00853               memcpy(entry_p->pass, &salt, sizeof(salt));
00854               memcpy(entry_p->pass + sizeof(salt), data_p->string, RSBAC_UM_PASS_LEN - sizeof(salt));
00855             }
00856           else
00857             memset(entry_p->pass, 0, RSBAC_UM_PASS_LEN);
00858           entry_p->lastchange = RSBAC_CURRENT_TIME / 86400;
00859           break;
00860 
00861         case UM_cryptpass:
00862           memcpy(entry_p->pass, data_p->string, RSBAC_UM_PASS_LEN);
00863           break;
00864 
00865         case UM_fullname:
00866           strncpy(entry_p->fullname, data_p->string, RSBAC_UM_FULLNAME_LEN);
00867           entry_p->fullname[RSBAC_UM_FULLNAME_LEN - 1] = 0;
00868           break;
00869 
00870         case UM_homedir:
00871           strncpy(entry_p->homedir, data_p->string, RSBAC_UM_HOMEDIR_LEN);
00872           entry_p->homedir[RSBAC_UM_HOMEDIR_LEN - 1] = 0;
00873           break;
00874 
00875         case UM_shell:
00876           strncpy(entry_p->shell, data_p->string, RSBAC_UM_SHELL_LEN);
00877           entry_p->shell[RSBAC_UM_SHELL_LEN - 1] = 0;
00878           break;
00879 
00880         case UM_group:
00881 #ifdef CONFIG_RSBAC_UM_EXCL
00882           if(!rsbac_um_no_excl && !rsbac_ta_list_exist(ta_number, group_handle[group_hash(data_p->group)], &data_p->group))
00883             {
00884 #ifdef CONFIG_RSBAC_RMSG
00885               rsbac_printk(KERN_INFO
00886                      "rsbac_um_mod_user(): gid %u not known to RSBAC User Management!\n",
00887                      data_p->group);
00888 #endif
00889 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00890               if (!rsbac_nosyslog)
00891 #endif
00892               printk(KERN_INFO
00893                      "rsbac_um_mod_user(): gid %u not known to RSBAC User Management!\n",
00894                      data_p->group);
00895               rsbac_kfree(entry_p);
00896               return -RSBAC_EINVALIDVALUE;
00897             }
00898 #endif
00899           entry_p->group = data_p->group;
00900           break;
00901 
00902         case UM_lastchange:
00903           entry_p->lastchange = data_p->days;
00904           break;
00905 
00906         case UM_minchange:
00907           entry_p->minchange = data_p->days;
00908           break;
00909 
00910         case UM_maxchange:
00911           entry_p->maxchange = data_p->days;
00912           break;
00913 
00914         case UM_warnchange:
00915           entry_p->warnchange = data_p->days;
00916           break;
00917 
00918         case UM_inactive:
00919           entry_p->inactive = data_p->days;
00920           break;
00921 
00922         case UM_expire:
00923           entry_p->expire = data_p->days;
00924           break;
00925 
00926         case UM_ttl:
00927           err = rsbac_ta_list_lol_add_ttl(ta_number, user_handle[user_hash(user)],
00928                                           data_p->ttl, &user, entry_p);
00929           rsbac_kfree(entry_p);
00930           return err;
00931 
00932         default:
00933           rsbac_kfree(entry_p);
00934           return -RSBAC_EINVALIDREQUEST;
00935       }
00936 
00937     err = rsbac_ta_list_lol_add_ttl(ta_number, user_handle[user_hash(user)],
00938                                     0, &user, entry_p);
00939     rsbac_kfree(entry_p);
00940     return err;
00941   }
00942 
00943 int rsbac_um_mod_group(
00944   rsbac_list_ta_number_t ta_number,
00945   rsbac_uid_t group,
00946   enum rsbac_um_mod_t mod,
00947   union rsbac_um_mod_data_t * data_p)
00948   {
00949     int err;
00950     struct rsbac_um_group_entry_t * entry_p;
00951 
00952     if (!rsbac_is_initialized())
00953       {
00954         printk(KERN_WARNING "rsbac_um_mod_group(): RSBAC not initialized\n");
00955         return(-RSBAC_ENOTINITIALIZED);
00956       }
00957     if(   !data_p
00958        && (mod != UM_pass)
00959       )
00960       return -RSBAC_EINVALIDPOINTER;
00961     if(!rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
00962       return -RSBAC_ENOTFOUND;
00963 
00964     entry_p = rsbac_kmalloc(sizeof(*entry_p));
00965     if(!entry_p)
00966       return -RSBAC_ENOMEM;
00967     err = rsbac_ta_list_get_data_ttl(ta_number, group_handle[group_hash(group)],
00968                                      NULL, &group, entry_p);
00969     if(err)
00970       {
00971         rsbac_kfree(entry_p);
00972         return err;
00973       }
00974 #ifdef CONFIG_RSBAC_DEBUG
00975       if (rsbac_debug_aef_um)
00976         {
00977 #ifdef CONFIG_RSBAC_RMSG
00978           rsbac_printk(KERN_DEBUG "rsbac_um_mod_group(): modifying group %u\n",
00979                        group);
00980 #endif
00981 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
00982           if (!rsbac_nosyslog)
00983 #endif
00984           printk(KERN_DEBUG "rsbac_um_mod_group(): modifying group %u\n",
00985                  group);
00986       }
00987 #endif
00988     switch(mod)
00989       {
00990         case UM_name:
00991           {
00992             rsbac_gid_t tmp_group;
00993 
00994             if(   !rsbac_um_get_gid(ta_number, data_p->string, &tmp_group)
00995                && (tmp_group != group)
00996               )
00997               return -RSBAC_EEXISTS;
00998             strncpy(entry_p->name, data_p->string, RSBAC_UM_NAME_LEN);
00999             entry_p->name[RSBAC_UM_NAME_LEN - 1] = 0;
01000           }
01001           break;
01002 
01003         case UM_pass:
01004           if(data_p)
01005             {
01006               __u32 salt;
01007 
01008               new_salt(&salt);
01009               err = rsbac_um_hash(data_p->string, salt);
01010               if(err)
01011                 {
01012                   rsbac_kfree(entry_p);
01013                   return err;
01014                 }
01015               memcpy(entry_p->pass, &salt, sizeof(salt));
01016               memcpy(entry_p->pass + sizeof(salt), data_p->string, RSBAC_UM_PASS_LEN - sizeof(salt));
01017             }
01018           else
01019             memset(entry_p->pass, 0, RSBAC_UM_PASS_LEN);
01020           break;
01021 
01022         case UM_cryptpass:
01023           memcpy(entry_p->pass, data_p->string, RSBAC_UM_PASS_LEN);
01024           break;
01025 
01026         case UM_ttl:
01027           err = rsbac_ta_list_add_ttl(ta_number, group_handle[group_hash(group)],
01028                                       data_p->ttl, &group, entry_p);
01029           rsbac_kfree(entry_p);
01030           return err;
01031 
01032         default:
01033           rsbac_kfree(entry_p);
01034           return -RSBAC_EINVALIDREQUEST;
01035       }
01036 
01037     err = rsbac_ta_list_add_ttl(ta_number, group_handle[group_hash(group)],
01038                                 0, &group, entry_p);
01039     rsbac_kfree(entry_p);
01040     return err;
01041   }
01042 
01043 int rsbac_um_get_user_item(
01044   rsbac_list_ta_number_t ta_number,
01045   rsbac_uid_t user,
01046   enum rsbac_um_mod_t mod,
01047   union rsbac_um_mod_data_t * data_p)
01048   {
01049     int err;
01050     struct rsbac_um_user_entry_t * entry_p;
01051 
01052     if (!rsbac_is_initialized())
01053       {
01054         printk(KERN_WARNING "rsbac_um_get_user_item(): RSBAC not initialized\n");
01055         return(-RSBAC_ENOTINITIALIZED);
01056       }
01057     if(!data_p)
01058       return -RSBAC_EINVALIDPOINTER;
01059     if(!rsbac_ta_list_lol_exist(ta_number, user_handle[user_hash(user)], &user))
01060       return -RSBAC_ENOTFOUND;
01061     if(mod == UM_ttl)
01062       return rsbac_ta_list_lol_get_data_ttl(ta_number, user_handle[user_hash(user)], &data_p->ttl, &user, NULL);
01063 
01064     entry_p = rsbac_kmalloc(sizeof(*entry_p));
01065     if(!entry_p)
01066       return -RSBAC_ENOMEM;
01067     err = rsbac_ta_list_lol_get_data_ttl(ta_number, user_handle[user_hash(user)],
01068                                          NULL, &user, entry_p);
01069     if(err)
01070       {
01071         rsbac_kfree(entry_p);
01072         return err;
01073       }
01074     switch(mod)
01075       {
01076         case UM_name:
01077           strcpy(data_p->string, entry_p->name);
01078           break;
01079 
01080         case UM_pass:
01081           memcpy(data_p->string, entry_p->pass, RSBAC_UM_PASS_LEN);
01082           break;
01083 
01084         case UM_fullname:
01085           strcpy(data_p->string, entry_p->fullname);
01086           break;
01087 
01088         case UM_homedir:
01089           strcpy(data_p->string, entry_p->homedir);
01090           break;
01091 
01092         case UM_shell:
01093           strcpy(data_p->string, entry_p->shell);
01094           break;
01095 
01096         case UM_group:
01097           data_p->group = entry_p->group;
01098           break;
01099 
01100         case UM_lastchange:
01101           data_p->days = entry_p->lastchange;
01102           break;
01103 
01104         case UM_minchange:
01105           data_p->days = entry_p->minchange;
01106           break;
01107 
01108         case UM_maxchange:
01109           data_p->days = entry_p->maxchange;
01110           break;
01111 
01112         case UM_warnchange:
01113           data_p->days = entry_p->warnchange;
01114           break;
01115 
01116         case UM_inactive:
01117           data_p->days = entry_p->inactive;
01118           break;
01119 
01120         case UM_expire:
01121           data_p->days = entry_p->expire;
01122           break;
01123 
01124         default:
01125           rsbac_kfree(entry_p);
01126           return -RSBAC_EINVALIDREQUEST;
01127       }
01128 
01129     rsbac_kfree(entry_p);
01130     return 0;
01131   }
01132 
01133 int rsbac_um_get_group_item(
01134   rsbac_list_ta_number_t ta_number,
01135   rsbac_gid_t group,
01136   enum rsbac_um_mod_t mod,
01137   union rsbac_um_mod_data_t * data_p)
01138   {
01139     int err;
01140     struct rsbac_um_group_entry_t * entry_p;
01141 
01142     if (!rsbac_is_initialized())
01143       {
01144         printk(KERN_WARNING "rsbac_um_get_group_item(): RSBAC not initialized\n");
01145         return(-RSBAC_ENOTINITIALIZED);
01146       }
01147     if(!data_p)
01148       return -RSBAC_EINVALIDPOINTER;
01149     if(!rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
01150       return -RSBAC_ENOTFOUND;
01151     if(mod == UM_ttl)
01152       return rsbac_ta_list_get_data_ttl(ta_number, group_handle[group_hash(group)], &data_p->ttl, &group, NULL);
01153 
01154     entry_p = rsbac_kmalloc(sizeof(*entry_p));
01155     if(!entry_p)
01156       return -RSBAC_ENOMEM;
01157     err = rsbac_ta_list_get_data_ttl(ta_number, group_handle[group_hash(group)],
01158                                      NULL, &group, entry_p);
01159     if(err)
01160       {
01161         rsbac_kfree(entry_p);
01162         return err;
01163       }
01164     switch(mod)
01165       {
01166         case UM_name:
01167           strcpy(data_p->string, entry_p->name);
01168           break;
01169 
01170         case UM_pass:
01171           memcpy(data_p->string, entry_p->pass, RSBAC_UM_PASS_LEN);
01172           break;
01173 
01174         default:
01175           rsbac_kfree(entry_p);
01176           return -RSBAC_EINVALIDREQUEST;
01177       }
01178 
01179     rsbac_kfree(entry_p);
01180     return 0;
01181   }
01182 
01183 int rsbac_um_user_exists(
01184   rsbac_list_ta_number_t ta_number,
01185   rsbac_uid_t user)
01186   {
01187     return rsbac_ta_list_lol_exist(ta_number, user_handle[user_hash(user)], &user);
01188   }
01189 
01190 int rsbac_um_group_exists(
01191   rsbac_list_ta_number_t ta_number,
01192   rsbac_gid_t group)
01193   {
01194     return rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group);
01195   }
01196 
01197 int rsbac_um_remove_user(
01198   rsbac_list_ta_number_t ta_number,
01199   rsbac_uid_t user)
01200   {
01201     if(!rsbac_ta_list_lol_exist(ta_number,user_handle[user_hash(user)], &user))
01202       return -RSBAC_ENOTFOUND;
01203     return rsbac_ta_list_lol_remove(ta_number, user_handle[user_hash(user)], &user);
01204   }
01205 
01206 int rsbac_um_remove_group(
01207   rsbac_list_ta_number_t ta_number,
01208   rsbac_gid_t group)
01209   {
01210     int i;
01211 
01212     if(!rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
01213       return -RSBAC_ENOTFOUND;
01214     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
01215       rsbac_ta_list_lol_subremove_from_all(ta_number, user_handle[i], &group);
01216     return rsbac_ta_list_remove(ta_number, group_handle[group_hash(group)], &group);
01217   }
01218 
01219 int rsbac_um_remove_gm(
01220   rsbac_list_ta_number_t ta_number,
01221   rsbac_uid_t user,
01222   rsbac_gid_t group)
01223   {
01224     if (!rsbac_is_initialized())
01225       {
01226         printk(KERN_WARNING "rsbac_um_remove_gm(): RSBAC not initialized\n");
01227         return(-RSBAC_ENOTINITIALIZED);
01228       }
01229 #ifdef CONFIG_RSBAC_DEBUG
01230       if (rsbac_debug_aef_um)
01231         {
01232 #ifdef CONFIG_RSBAC_RMSG
01233           rsbac_printk(KERN_DEBUG "rsbac_um_remove_gm(): removing user %u group %u\n",
01234                        user,
01235                        group);
01236 #endif
01237 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01238           if (!rsbac_nosyslog)
01239 #endif
01240           printk(KERN_DEBUG "rsbac_um_remove_gm(): removing user %u group %u\n",
01241                  user,
01242                  group);
01243       }
01244 #endif
01245     return rsbac_ta_list_lol_subremove(ta_number, user_handle[user_hash(user)], &user, &group);
01246   }
01247 
01248 int rsbac_um_get_user_entry(
01249   rsbac_list_ta_number_t ta_number,
01250   rsbac_uid_t user,
01251   struct rsbac_um_user_entry_t * entry_p,
01252   rsbac_time_t * ttl_p)
01253   {
01254     return rsbac_ta_list_lol_get_data_ttl(ta_number, user_handle[user_hash(user)], ttl_p, &user, entry_p);
01255   }
01256 
01257 int rsbac_um_get_next_user(
01258   rsbac_list_ta_number_t ta_number,
01259   rsbac_uid_t old_user,
01260   rsbac_uid_t * next_user_p)
01261   {
01262     rsbac_uid_t * old_user_p;
01263     int i;
01264     int err;
01265 
01266     if(old_user == RSBAC_NO_USER)
01267       old_user_p = NULL;
01268     else
01269       old_user_p = &old_user;
01270 
01271     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
01272       {
01273         err = rsbac_ta_list_lol_get_next_desc(ta_number, user_handle[i], old_user_p, next_user_p);
01274         if(err != -RSBAC_ENOTFOUND)
01275           return err;
01276       }
01277     return -RSBAC_ENOTFOUND;
01278   }
01279 
01280 int rsbac_um_get_user_list(
01281   rsbac_list_ta_number_t ta_number,
01282   rsbac_uid_t ** list_pp)
01283   {
01284     int i;
01285     long all_count = 0;
01286     long copy_count = 0;
01287     long tmp_count;
01288     rsbac_uid_t * tmp_list_p;
01289     rsbac_uid_t * collect_list_p;
01290     rsbac_uid_t * p;
01291 
01292     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
01293       {
01294         tmp_count = rsbac_ta_list_lol_count(ta_number, user_handle[i]);
01295         if(tmp_count > 0)
01296           all_count += tmp_count;
01297       }
01298     if(!list_pp || !all_count)
01299       return all_count;
01300 
01301     /* provide some extra room in case new users have been added during this function run */
01302     all_count += EXTRA_ROOM;
01303     collect_list_p = rsbac_vmalloc(all_count * sizeof(rsbac_uid_t));
01304     if(!collect_list_p)
01305       return -RSBAC_ENOMEM;
01306     p = collect_list_p;
01307     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
01308       {
01309         tmp_count = rsbac_ta_list_lol_get_all_desc(ta_number, user_handle[i], (void *) &tmp_list_p);
01310         if(tmp_count > 0)
01311           {
01312             tmp_count = rsbac_min(tmp_count, all_count - copy_count);
01313             if(tmp_count)
01314               memcpy(p, tmp_list_p, tmp_count * sizeof(rsbac_uid_t));
01315             rsbac_vfree(tmp_list_p);
01316             p += tmp_count;
01317             copy_count += tmp_count;
01318             if(copy_count >= all_count)
01319               break;
01320           }
01321       }
01322     if(!copy_count)
01323       rsbac_vfree(collect_list_p);
01324     else
01325       *list_pp = collect_list_p;
01326     return copy_count;
01327   }
01328 
01329 int rsbac_um_get_gm_list(
01330   rsbac_list_ta_number_t ta_number,
01331   rsbac_uid_t user,
01332   rsbac_gid_t ** list_pp)
01333   {
01334     if(!list_pp)
01335       return rsbac_ta_list_lol_subcount(ta_number, user_handle[user_hash(user)], &user);
01336     else
01337       return rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number, user_handle[user_hash(user)],
01338                                                    &user, (void **) list_pp, NULL);
01339   }
01340 
01341 int rsbac_um_get_gm_user_list(
01342   rsbac_list_ta_number_t ta_number,
01343   rsbac_gid_t group,
01344   rsbac_uid_t ** list_pp)
01345   {
01346     int i;
01347     int j;
01348     long all_count = 0;
01349     long copy_count = 0;
01350     long tmp_count;
01351     rsbac_uid_t * tmp_list_p;
01352     rsbac_uid_t * collect_list_p;
01353     rsbac_uid_t * p;
01354 
01355 #ifdef CONFIG_RSBAC_UM_EXCL
01356     if(!rsbac_um_no_excl && !rsbac_ta_list_exist(ta_number, group_handle[group_hash(group)], &group))
01357       {
01358         return -RSBAC_ENOTFOUND;
01359       }
01360 #endif
01361     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
01362       {
01363         tmp_count = rsbac_ta_list_lol_count(ta_number, user_handle[i]);
01364         if(tmp_count > 0)
01365           all_count += tmp_count;
01366       }
01367     if(!list_pp || !all_count)
01368       return all_count;
01369 
01370     /* provide some extra room in case new groups have been added during this function run */
01371     all_count += EXTRA_ROOM;
01372     collect_list_p = rsbac_vmalloc(all_count * sizeof(rsbac_uid_t));
01373     if(!collect_list_p)
01374       return -RSBAC_ENOMEM;
01375     p = collect_list_p;
01376     for(i=0; i<RSBAC_UM_NR_USER_LISTS; i++)
01377       {
01378         tmp_count = rsbac_ta_list_lol_get_all_desc(ta_number, user_handle[i], (void *) &tmp_list_p);
01379         if(tmp_count > 0)
01380           {
01381             tmp_count = rsbac_min(tmp_count, all_count - copy_count);
01382             for(j=0; j<tmp_count; j++)
01383               {
01384                 if(rsbac_ta_list_lol_subexist(ta_number, user_handle[i], &tmp_list_p[j], &group))
01385                   {
01386                     *p = tmp_list_p[j];
01387                     p++;
01388                     copy_count++;
01389                   }
01390               }
01391             rsbac_vfree(tmp_list_p);
01392             if(copy_count >= all_count)
01393               break;
01394           }
01395       }
01396     if(!copy_count)
01397       rsbac_vfree(collect_list_p);
01398     else
01399       *list_pp = collect_list_p;
01400     return copy_count;
01401   }
01402 
01403 int rsbac_um_get_group_list(
01404   rsbac_list_ta_number_t ta_number,
01405   rsbac_gid_t ** list_pp)
01406   {
01407     int i;
01408     long all_count = 0;
01409     long copy_count = 0;
01410     long tmp_count;
01411     rsbac_gid_t * tmp_list_p;
01412     rsbac_gid_t * collect_list_p;
01413     rsbac_gid_t * p;
01414 
01415     for(i=0; i<RSBAC_UM_NR_GROUP_LISTS; i++)
01416       {
01417         tmp_count = rsbac_ta_list_count(ta_number, group_handle[i]);
01418         if(tmp_count > 0)
01419           all_count += tmp_count;
01420       }
01421     if(!list_pp || !all_count)
01422       return all_count;
01423 
01424     /* provide some extra room in case new groups have been added during this function run */
01425     all_count += EXTRA_ROOM;
01426     collect_list_p = rsbac_vmalloc(all_count * sizeof(rsbac_gid_t));
01427     if(!collect_list_p)
01428       return -RSBAC_ENOMEM;
01429     p = collect_list_p;
01430     for(i=0; i<RSBAC_UM_NR_GROUP_LISTS; i++)
01431       {
01432         tmp_count = rsbac_ta_list_get_all_desc(ta_number, group_handle[i], (void *) &tmp_list_p);
01433         if(tmp_count > 0)
01434           {
01435             tmp_count = rsbac_min(tmp_count, all_count - copy_count);
01436             if(tmp_count)
01437               memcpy(p, tmp_list_p, tmp_count * sizeof(rsbac_gid_t));
01438             rsbac_vfree(tmp_list_p);
01439             p += tmp_count;
01440             copy_count += tmp_count;
01441             if(copy_count >= all_count)
01442               break;
01443           }
01444       }
01445     if(!copy_count)
01446       rsbac_vfree(collect_list_p);
01447     else
01448       *list_pp = collect_list_p;
01449     return copy_count;
01450   }
01451 
01452 int rsbac_um_check_pass(rsbac_uid_t uid,
01453                         char * pass)
01454   {
01455       int err;
01456       struct rsbac_um_user_entry_t * entry_p;
01457       __u32 salt;
01458       u_long curdays;
01459 
01460       if(!pass)
01461         return -RSBAC_EINVALIDPOINTER;
01462       entry_p = rsbac_kmalloc(sizeof(*entry_p));
01463       if(!entry_p)
01464         return -RSBAC_ENOMEM;
01465       err = rsbac_ta_list_lol_get_data_ttl(0, user_handle[user_hash(uid)],
01466                                            NULL, &uid, entry_p);
01467       if(err)
01468         goto out_free;
01469 
01470 #ifdef CONFIG_RSBAC_DEBUG
01471       if (rsbac_debug_aef_um)
01472         {
01473 #ifdef CONFIG_RSBAC_RMSG
01474           rsbac_printk(KERN_DEBUG "rsbac_um_check_pass(): checking password for user %u\n",
01475                        uid);
01476 #endif
01477 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01478           if (!rsbac_nosyslog)
01479 #endif
01480           printk(KERN_DEBUG "rsbac_um_check_pass(): checking password for user %u\n",
01481                  uid);
01482       }
01483 #endif
01484       /* check whether account or password has expired */
01485       curdays = RSBAC_CURRENT_TIME / 86400;
01486       if ((curdays > entry_p->expire) && (entry_p->expire != -1)
01487             && (entry_p->expire != 0) && (entry_p->lastchange != 0))
01488         {
01489           err = -RSBAC_EEXPIRED;
01490 #ifdef CONFIG_RSBAC_DEBUG
01491           if (rsbac_debug_aef_um)
01492             {
01493 #ifdef CONFIG_RSBAC_RMSG
01494               rsbac_printk(KERN_DEBUG "rsbac_um_check_pass(): account for user %u has expired\n",
01495                            uid);
01496 #endif
01497 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01498               if (!rsbac_nosyslog)
01499 #endif
01500               printk(KERN_DEBUG "rsbac_um_check_pass(): account for user %u has expired\n",
01501                      uid);
01502       }
01503 #endif
01504           goto out_free;
01505         }
01506       if(   (curdays > (entry_p->lastchange + entry_p->maxchange + entry_p->inactive))
01507          && (entry_p->maxchange != -1)
01508          && (entry_p->maxchange)
01509          && (entry_p->inactive != -1)
01510          && (entry_p->inactive)
01511          && (entry_p->lastchange)
01512         )
01513         {
01514           err = -RSBAC_EEXPIRED;
01515 #ifdef CONFIG_RSBAC_DEBUG
01516           if (rsbac_debug_aef_um)
01517             {
01518 #ifdef CONFIG_RSBAC_RMSG
01519               rsbac_printk(KERN_DEBUG "rsbac_um_check_pass(): password for user %u has expired\n",
01520                            uid);
01521 #endif
01522 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01523               if (!rsbac_nosyslog)
01524 #endif
01525               printk(KERN_DEBUG "rsbac_um_check_pass(): password for user %u has expired\n",
01526                      uid);
01527       }
01528 #endif
01529           goto out_free;
01530         }
01531 
01532       salt = *((__u32*) entry_p->pass);
01533       if(!salt)
01534         {
01535           err = -EPERM;
01536           goto out_free;
01537         }
01538       err = rsbac_um_hash(pass, salt);
01539       if(err)
01540         return err;
01541       if(memcmp(pass, entry_p->pass + sizeof(salt), RSBAC_UM_PASS_LEN - sizeof(salt)))
01542         err = -EPERM;
01543       else
01544         err = 0;
01545 
01546 out_free:
01547       rsbac_kfree(entry_p);
01548       if(err)
01549         ssleep(1);
01550       return err;
01551   }
01552 
01553 int rsbac_um_set_pass(rsbac_uid_t uid,
01554                       char * pass)
01555   {
01556       int err;
01557       struct rsbac_um_user_entry_t * entry_p;
01558       __u32 salt;
01559 
01560       entry_p = rsbac_kmalloc(sizeof(*entry_p));
01561       if(!entry_p)
01562         return -RSBAC_ENOMEM;
01563       err = rsbac_ta_list_lol_get_data_ttl(0, user_handle[user_hash(uid)],
01564                                            NULL, &uid, entry_p);
01565       if(err)
01566         goto out_free;
01567 
01568 #ifdef CONFIG_RSBAC_DEBUG
01569       if (rsbac_debug_aef_um)
01570         {
01571 #ifdef CONFIG_RSBAC_RMSG
01572           rsbac_printk(KERN_DEBUG "rsbac_um_set_pass(): setting password for user %u\n",
01573                        uid);
01574 #endif
01575 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01576           if (!rsbac_nosyslog)
01577 #endif
01578           printk(KERN_DEBUG "rsbac_um_set_pass(): setting password for user %u\n",
01579                  uid);
01580       }
01581 #endif
01582       if(pass)
01583         {
01584           new_salt(&salt);
01585           err = rsbac_um_hash(pass, salt);
01586           if(err)
01587             goto out_free;
01588           memcpy(entry_p->pass, &salt, sizeof(salt));
01589           memcpy(entry_p->pass + sizeof(salt), pass, RSBAC_UM_PASS_LEN - sizeof(salt));
01590         }
01591       else
01592         memset(entry_p->pass, 0, RSBAC_UM_PASS_LEN);
01593       entry_p->lastchange = RSBAC_CURRENT_TIME / 86400;
01594       err = rsbac_ta_list_lol_add_ttl(0, user_handle[user_hash(uid)],
01595                                       0, &uid, entry_p);
01596 
01597 out_free:
01598       rsbac_kfree(entry_p);
01599       return err;
01600   }
01601 
01602 int rsbac_um_set_group_pass(rsbac_gid_t gid,
01603                             char * pass)
01604   {
01605       int err;
01606       struct rsbac_um_group_entry_t * entry_p;
01607       __u32 salt;
01608 
01609       entry_p = rsbac_kmalloc(sizeof(*entry_p));
01610       if(!entry_p)
01611         return -RSBAC_ENOMEM;
01612       err = rsbac_ta_list_get_data_ttl(0, group_handle[group_hash(gid)],
01613                                        NULL, &gid, entry_p);
01614       if(err)
01615         goto out_free;
01616 
01617 #ifdef CONFIG_RSBAC_DEBUG
01618       if (rsbac_debug_aef_um)
01619         {
01620 #ifdef CONFIG_RSBAC_RMSG
01621           rsbac_printk(KERN_DEBUG "rsbac_um_set_group_pass(): setting password for group %u\n",
01622                        gid);
01623 #endif
01624 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01625           if (!rsbac_nosyslog)
01626 #endif
01627           printk(KERN_DEBUG "rsbac_um_set_group_pass(): setting password for group %u\n",
01628                  gid);
01629       }
01630 #endif
01631       if(pass)
01632         {
01633           new_salt(&salt);
01634           err = rsbac_um_hash(pass, salt);
01635           if(err)
01636             goto out_free;
01637           memcpy(entry_p->pass, &salt, sizeof(salt));
01638           memcpy(entry_p->pass + sizeof(salt), pass, RSBAC_UM_PASS_LEN - sizeof(salt));
01639         }
01640       else
01641         memset(entry_p->pass, 0, RSBAC_UM_PASS_LEN);
01642       err = rsbac_ta_list_add_ttl(0, group_handle[group_hash(gid)], 0, &gid, entry_p);
01643 
01644 out_free:
01645       rsbac_kfree(entry_p);
01646       return err;
01647   }
01648 
01649 int rsbac_um_check_account(rsbac_uid_t uid)
01650   {
01651       int err;
01652       struct rsbac_um_user_entry_t * entry_p;
01653       u_long curdays;
01654 
01655       entry_p = rsbac_kmalloc(sizeof(*entry_p));
01656       if(!entry_p)
01657         return -RSBAC_ENOMEM;
01658       err = rsbac_ta_list_lol_get_data_ttl(0, user_handle[user_hash(uid)],
01659                                            NULL, &uid, entry_p);
01660       if(err)
01661         goto out_free;
01662 
01663 #ifdef CONFIG_RSBAC_DEBUG
01664       if (rsbac_debug_aef_um)
01665         {
01666 #ifdef CONFIG_RSBAC_RMSG
01667           rsbac_printk(KERN_DEBUG "rsbac_um_check_account(): checking account for user %u\n",
01668                        uid);
01669 #endif
01670 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01671           if (!rsbac_nosyslog)
01672 #endif
01673           printk(KERN_DEBUG "rsbac_um_check_account(): checking account for user %u\n",
01674                  uid);
01675       }
01676 #endif
01677       /* check whether account or password has expired */
01678       curdays = RSBAC_CURRENT_TIME / 86400;
01679       if(   *((__u32*) entry_p->pass)
01680          && !entry_p->lastchange
01681         )
01682         {
01683           err = -RSBAC_EMUSTCHANGE;
01684 #ifdef CONFIG_RSBAC_DEBUG
01685           if (rsbac_debug_aef_um)
01686             {
01687 #ifdef CONFIG_RSBAC_RMSG
01688               rsbac_printk(KERN_DEBUG "rsbac_um_check_account(): user %u must change password, lastchange = 0\n",
01689                            uid);
01690 #endif
01691 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01692               if (!rsbac_nosyslog)
01693 #endif
01694               printk(KERN_DEBUG "rsbac_um_check_account(): user %u must change password, lastchange = 0\n",
01695                      uid);
01696             }
01697 #endif
01698           goto out_free;
01699         }
01700       if(  (curdays > entry_p->expire)
01701          && (entry_p->expire != -1)
01702          && (entry_p->expire)
01703         )
01704         {
01705           err = -RSBAC_EEXPIRED;
01706 #ifdef CONFIG_RSBAC_DEBUG
01707           if (rsbac_debug_aef_um)
01708             {
01709 #ifdef CONFIG_RSBAC_RMSG
01710               rsbac_printk(KERN_DEBUG "rsbac_um_check_account(): account for user %u has expired\n",
01711                            uid);
01712 #endif
01713 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01714               if (!rsbac_nosyslog)
01715 #endif
01716               printk(KERN_DEBUG "rsbac_um_check_account(): account for user %u has expired\n",
01717                      uid);
01718             }
01719 #endif
01720           goto out_free;
01721         }
01722       if(   (curdays > (entry_p->lastchange + entry_p->maxchange + entry_p->inactive))
01723          && (entry_p->maxchange != -1)
01724          && (entry_p->maxchange)
01725          && (entry_p->inactive != -1)
01726          && (entry_p->inactive)
01727         )
01728         {
01729           err = -RSBAC_EEXPIRED;
01730 #ifdef CONFIG_RSBAC_DEBUG
01731           if (rsbac_debug_aef_um)
01732             {
01733 #ifdef CONFIG_RSBAC_RMSG
01734               rsbac_printk(KERN_DEBUG "rsbac_um_check_account(): password for user %u has expired\n",
01735                            uid);
01736 #endif
01737 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01738               if (!rsbac_nosyslog)
01739 #endif
01740               printk(KERN_DEBUG "rsbac_um_check_account(): password for user %u has expired\n",
01741                      uid);
01742             }
01743 #endif
01744           goto out_free;
01745         }
01746       if(   ((entry_p->lastchange + entry_p->maxchange) < curdays)
01747          && entry_p->maxchange
01748          && (entry_p->maxchange != -1)
01749         )
01750         {
01751           err = -RSBAC_EMUSTCHANGE;
01752 #ifdef CONFIG_RSBAC_DEBUG
01753           if (rsbac_debug_aef_um)
01754             {
01755 #ifdef CONFIG_RSBAC_RMSG
01756               rsbac_printk(KERN_DEBUG "rsbac_um_check_account(): user %u must change password, lastchange too old\n",
01757                            uid);
01758 #endif
01759 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG
01760               if (!rsbac_nosyslog)
01761 #endif
01762               printk(KERN_DEBUG "rsbac_um_check_account(): user %u must change password, lastchange too old\n",
01763                      uid);
01764             }
01765 #endif
01766           goto out_free;
01767         }
01768       if(   (curdays > (entry_p->lastchange + entry_p->maxchange - entry_p->warnchange))
01769          && (entry_p->maxchange != -1)
01770          && (entry_p->warnchange != -1)
01771          && entry_p->maxchange
01772          && entry_p->warnchange
01773         )
01774         {
01775           err = (entry_p->lastchange + entry_p->maxchange) - curdays;
01776         }
01777       else
01778         err = 0;
01779 
01780 out_free:
01781       rsbac_kfree(entry_p);
01782       return err;
01783   }
01784 
01785 
01786 /* end of um_data_structures.c */

Generated on Fri Jun 17 09:45:25 2005 for RSBAC by  doxygen 1.4.2