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

Generated on Sun May 21 14:30:55 2006 for RSBAC by  doxygen 1.4.2