00001
00002
00003
00004
00005
00006
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
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
00045
00046
00047
00048
00049
00050
00051
00052
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
00082 rsbac_read_lock(&device_list_head.lock, &dflags);
00083
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
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
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
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
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
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
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
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
00403
00404
00405
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
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
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
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
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
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
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