login_cap.c (23144) | login_cap.c (25670) |
---|---|
1/*- 2 * Copyright (c) 1996 by 3 * Sean Eric Fagan <sef@kithrup.com> 4 * David Nugent <davidn@blaze.net.au> 5 * All rights reserved. 6 * | 1/*- 2 * Copyright (c) 1996 by 3 * Sean Eric Fagan <sef@kithrup.com> 4 * David Nugent <davidn@blaze.net.au> 5 * All rights reserved. 6 * |
7 * Portions copyright (c) 1995,1997 8 * Berkeley Software Design, Inc. 9 * All rights reserved. 10 * |
|
7 * Redistribution and use in source and binary forms, with or without 8 * modification, is permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice immediately at the beginning of the file, without modification, 12 * this list of conditions, and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. This work was done expressly for inclusion into FreeBSD. Other use 17 * is permitted provided this notation is included. 18 * 4. Absolutely no warranty of function or purpose is made by the authors. 19 * 5. Modifications may be freely made to this file providing the above 20 * conditions are met. 21 * 22 * Low-level routines relating to the user capabilities database 23 * | 11 * Redistribution and use in source and binary forms, with or without 12 * modification, is permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice immediately at the beginning of the file, without modification, 16 * this list of conditions, and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. This work was done expressly for inclusion into FreeBSD. Other use 21 * is permitted provided this notation is included. 22 * 4. Absolutely no warranty of function or purpose is made by the authors. 23 * 5. Modifications may be freely made to this file providing the above 24 * conditions are met. 25 * 26 * Low-level routines relating to the user capabilities database 27 * |
24 * $Id: login_cap.c,v 1.10 1997/02/22 15:08:20 peter Exp $ | 28 * $Id: login_cap.c,v 1.11 1997/02/27 00:24:05 ache Exp $ |
25 */ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <errno.h> | 29 */ 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <string.h> 34#include <errno.h> |
35#include <fcntl.h> |
|
31#include <unistd.h> 32 33#include <sys/types.h> 34#include <sys/time.h> 35#include <sys/resource.h> 36#include <sys/param.h> 37#include <pwd.h> | 36#include <unistd.h> 37 38#include <sys/types.h> 39#include <sys/time.h> 40#include <sys/resource.h> 41#include <sys/param.h> 42#include <pwd.h> |
43#include <libutil.h> 44#include <syslog.h> |
|
38#include <login_cap.h> 39 | 45#include <login_cap.h> 46 |
40#ifdef RLIM_LONG 41# define STRTOV strtol 42#else 43# define STRTOV strtoq 44#endif | 47/* 48 * allocstr() 49 * Manage a single static pointer for handling a local char* buffer, 50 * resizing as necessary to contain the string. 51 * 52 * allocarray() 53 * Manage a static array for handling a group of strings, resizing 54 * when necessary. 55 */ |
45 46static int lc_object_count = 0; 47 48static size_t internal_stringsz = 0; 49static char * internal_string = NULL; 50static size_t internal_arraysz = 0; 51static char ** internal_array = NULL; 52 53static char * | 56 57static int lc_object_count = 0; 58 59static size_t internal_stringsz = 0; 60static char * internal_string = NULL; 61static size_t internal_arraysz = 0; 62static char ** internal_array = NULL; 63 64static char * |
54allocstr(char * str) | 65allocstr(char *str) |
55{ | 66{ |
56 char * p; 57 size_t sz = strlen(str) + 1; /* realloc() only if necessary */ 58 if (sz <= internal_stringsz) 59 p = strcpy(internal_string, str); 60 else if ((p = realloc(internal_string, sz)) != NULL) { 61 internal_stringsz = sz; 62 internal_string = strcpy(p, str); 63 } 64 return p; | 67 char *p; 68 69 size_t sz = strlen(str) + 1; /* realloc() only if necessary */ 70 if (sz <= internal_stringsz) 71 p = strcpy(internal_string, str); 72 else if ((p = realloc(internal_string, sz)) != NULL) { 73 internal_stringsz = sz; 74 internal_string = strcpy(p, str); 75 } 76 return p; |
65} 66 | 77} 78 |
79 |
|
67static char ** 68allocarray(size_t sz) 69{ | 80static char ** 81allocarray(size_t sz) 82{ |
70 char ** p; 71 if (sz <= internal_arraysz) 72 p = internal_array; 73 else if ((p = realloc(internal_array, sz * sizeof(char*))) != NULL) { 74 internal_arraysz = sz; 75 internal_array = p; 76 } 77 return p; | 83 char **p; 84 85 if (sz <= internal_arraysz) 86 p = internal_array; 87 else if ((p = realloc(internal_array, sz * sizeof(char*))) != NULL) { 88 internal_arraysz = sz; 89 internal_array = p; 90 } 91 return p; |
78} 79 80 81/* 82 * arrayize() 83 * Turn a simple string <str> seperated by any of 84 * the set of <chars> into an array. The last element 85 * of the array will be NULL, as is proper. 86 * Free using freearraystr() 87 */ 88 89static char ** 90arrayize(char *str, const char *chars, int *size) 91{ | 92} 93 94 95/* 96 * arrayize() 97 * Turn a simple string <str> seperated by any of 98 * the set of <chars> into an array. The last element 99 * of the array will be NULL, as is proper. 100 * Free using freearraystr() 101 */ 102 103static char ** 104arrayize(char *str, const char *chars, int *size) 105{ |
92 int i; 93 char *ptr; 94 char **res = NULL; | 106 int i; 107 char *ptr; 108 char **res = NULL; |
95 | 109 |
96 for (i = 0, ptr = str; *ptr; i++) { 97 int count = strcspn(ptr, chars); 98 ptr += count; 99 if (*ptr) 100 ++ptr; 101 } | 110 /* count the sub-strings */ 111 for (i = 0, ptr = str; *ptr; i++) { 112 int count = strcspn(ptr, chars); 113 ptr += count; 114 if (*ptr) 115 ++ptr; 116 } |
102 | 117 |
103 if ((ptr = allocstr(str)) == NULL) { 104 res = NULL; | |
105 i = 0; | 118 i = 0; |
106 } else if ((res = allocarray(++i)) == NULL) { 107 free(str); 108 i = 0; 109 } else { 110 for (i = 0; *ptr; i++) { 111 int count = strcspn(ptr, chars); 112 res[i] = ptr; 113 ptr += count; 114 if (*ptr) 115 *ptr++ = '\0'; | 119 /* alloc the array */ 120 if ((ptr = allocstr(str)) != NULL) { 121 if ((res = allocarray(++i)) == NULL) 122 free(str); 123 else { 124 /* now split the string */ 125 while (*ptr) { 126 int count = strcspn(ptr, chars); 127 res[i++] = ptr; 128 ptr += count; 129 if (*ptr) 130 *ptr++ = '\0'; 131 } 132 res[i] = NULL; 133 } |
116 } | 134 } |
117 res[i] = 0; 118 } 119 if (size) 120 *size = i; 121 return res; | 135 136 if (size) 137 *size = i; 138 139 return res; |
122} 123 | 140} 141 |
142 |
|
124/* 125 * login_close() 126 * Frees up all resources relating to a login class 127 * 128 */ 129 130void 131login_close(login_cap_t * lc) 132{ | 143/* 144 * login_close() 145 * Frees up all resources relating to a login class 146 * 147 */ 148 149void 150login_close(login_cap_t * lc) 151{ |
133 if (lc) { 134 free(lc->lc_style); 135 free(lc->lc_class); 136 free(lc); 137 if (--lc_object_count == 0) { 138 free(internal_string); 139 free(internal_array); 140 internal_array = NULL; 141 internal_arraysz = 0; 142 internal_string = NULL; 143 internal_stringsz = 0; 144 cgetclose(); | 152 if (lc) { 153 free(lc->lc_style); 154 free(lc->lc_class); 155 free(lc); 156 if (--lc_object_count == 0) { 157 free(internal_string); 158 free(internal_array); 159 internal_array = NULL; 160 internal_arraysz = 0; 161 internal_string = NULL; 162 internal_stringsz = 0; 163 cgetclose(); 164 } |
145 } | 165 } |
146 } | |
147} 148 149 150/* 151 * login_getclassbyname() get the login class by its name. 152 * If the name given is NULL or empty, the default class 153 * LOGIN_DEFCLASS (ie. "default") is fetched. If the 154 * 'dir' argument contains a non-NULL non-empty string, 155 * then the file _FILE_LOGIN_CONF is picked up from that 156 * directory instead of the system login database. 157 * Return a filled-out login_cap_t structure, including 158 * class name, and the capability record buffer. 159 */ 160 161login_cap_t * | 166} 167 168 169/* 170 * login_getclassbyname() get the login class by its name. 171 * If the name given is NULL or empty, the default class 172 * LOGIN_DEFCLASS (ie. "default") is fetched. If the 173 * 'dir' argument contains a non-NULL non-empty string, 174 * then the file _FILE_LOGIN_CONF is picked up from that 175 * directory instead of the system login database. 176 * Return a filled-out login_cap_t structure, including 177 * class name, and the capability record buffer. 178 */ 179 180login_cap_t * |
162login_getclassbyname(char const * name, char const * dir) | 181login_getclassbyname(char const *name, const struct passwd *pwd) |
163{ | 182{ |
164 login_cap_t *lc = malloc(sizeof(login_cap_t)); | 183 login_cap_t *lc; |
165 | 184 |
166 if (lc != NULL) { 167 int i = 0; 168 char userpath[MAXPATHLEN]; 169 static char *login_dbarray[] = { NULL, NULL, NULL }; | 185 if ((lc = malloc(sizeof(login_cap_t))) != NULL) { 186 int r, i = 0; 187 const char *msg = NULL; 188 const char *dir = (pwd == NULL) ? NULL : pwd->pw_dir; 189 char userpath[MAXPATHLEN]; |
170 | 190 |
171 if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, _FILE_LOGIN_CONF) < MAXPATHLEN) 172 login_dbarray[i++] = userpath; 173 else 174 login_dbarray[i++] = _PATH_LOGIN_CONF; 175 login_dbarray[i ] = NULL; | 191 static char *login_dbarray[] = { NULL, NULL, NULL }; |
176 | 192 |
177 lc->lc_cap = lc->lc_class = lc->lc_style = NULL; | 193 if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, 194 _FILE_LOGIN_CONF) < MAXPATHLEN) { 195 login_dbarray[i] = userpath; 196 if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) 197 i++; /* only use 'secure' data */ 198 } 199 if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1) 200 login_dbarray[i++] = _PATH_LOGIN_CONF; 201 login_dbarray[i] = NULL; |
178 | 202 |
179 if ((name == NULL || cgetent(&lc->lc_cap, login_dbarray, (char*)name) != 0) && 180 cgetent(&lc->lc_cap, login_dbarray, (char*)(name = LOGIN_DEFCLASS)) != 0) { | 203 memset(lc, 0, sizeof(login_cap_t)); 204 lc->lc_cap = lc->lc_class = lc->lc_style = NULL; 205 206 if (name == NULL || *name == '\0') 207 name = LOGIN_DEFCLASS; 208 209 switch (cgetent(&lc->lc_cap, login_dbarray, (char*)name)) { 210 case -1: /* Failed, entry does not exist */ 211 if (strcmp(name, LOGIN_MECLASS) == 0) 212 break; /* Don't retry default on 'me' */ 213 if (i == 0) 214 r = -1; 215 else if ((r = open(login_dbarray[0], O_RDONLY)) >= 0) 216 close(r); 217 /* 218 * If there's at least one login class database, 219 * and we aren't searching for a default class 220 * then complain about a non-existent class. 221 */ 222 if (r >= 0 || strcmp(name, LOGIN_DEFCLASS) != 0) 223 syslog(LOG_ERR, "login_getclass: unknown class '%s'", name); 224 /* fall-back to default class */ 225 name = LOGIN_DEFCLASS; 226 msg = "%s: no default/fallback class '%s'"; 227 if (cgetent(&lc->lc_cap, login_dbarray, (char*)name) != 0 && r >= 0) 228 break; 229 /* Fallthru - just return system defaults */ 230 case 0: /* success! */ 231 if ((lc->lc_class = strdup(name)) != NULL) { 232 ++lc_object_count; 233 return lc; 234 } 235 msg = "%s: strdup: %m"; 236 break; 237 case -2: 238 msg = "%s: retrieving class information: %m"; 239 break; 240 case -3: 241 msg = "%s: 'tc=' reference loop '%s'"; 242 break; 243 case 1: 244 msg = "couldn't resolve 'tc=' reference in '%s'"; 245 break; 246 default: 247 msg = "%s: unexpected cgetent() error '%s': %m"; 248 break; 249 } 250 if (msg != NULL) 251 syslog(LOG_ERR, msg, "login_getclass", name); |
181 free(lc); | 252 free(lc); |
182 lc = NULL; 183 } else { 184 ++lc_object_count; 185 lc->lc_class = strdup(name); | |
186 } | 253 } |
187 } | |
188 | 254 |
189 return lc; | 255 return NULL; |
190} 191 192 193 194/* 195 * login_getclass() | 256} 257 258 259 260/* 261 * login_getclass() |
262 * Get the login class for the system (only) login class database. 263 * Return a filled-out login_cap_t structure, including 264 * class name, and the capability record buffer. 265 */ 266 267login_cap_t * 268login_getclass(const char *cls) 269{ 270 return login_getclassbyname(cls, NULL); 271} 272 273 274/* 275 * login_getclass() |
|
196 * Get the login class for a given password entry from 197 * the system (only) login class database. 198 * If the password entry's class field is not set, or 199 * the class specified does not exist, then use the 200 * default of LOGIN_DEFCLASS (ie. "default"). 201 * Return a filled-out login_cap_t structure, including 202 * class name, and the capability record buffer. 203 */ 204 205login_cap_t * | 276 * Get the login class for a given password entry from 277 * the system (only) login class database. 278 * If the password entry's class field is not set, or 279 * the class specified does not exist, then use the 280 * default of LOGIN_DEFCLASS (ie. "default"). 281 * Return a filled-out login_cap_t structure, including 282 * class name, and the capability record buffer. 283 */ 284 285login_cap_t * |
206login_getclass(const struct passwd *pwd) | 286login_getpwclass(const struct passwd *pwd) |
207{ | 287{ |
208 const char * class = NULL; 209 if (pwd != NULL) { 210 if ((class = pwd->pw_class) == NULL || *class == '\0') 211 class = (pwd->pw_uid == 0) ? "root" : NULL; 212 } 213 return login_getclassbyname(class, 0); | 288 const char *cls = NULL; 289 290 if (pwd != NULL) { 291 cls = pwd->pw_class; 292 if (cls == NULL || *cls == '\0') 293 cls = (pwd->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS; 294 } 295 return login_getclassbyname(cls, pwd); |
214} 215 216 217/* 218 * login_getuserclass() 219 * Get the login class for a given password entry, allowing user 220 * overrides via ~/.login_conf. | 296} 297 298 299/* 300 * login_getuserclass() 301 * Get the login class for a given password entry, allowing user 302 * overrides via ~/.login_conf. |
221 * ### WAS: If the password entry's class field is not set, 222 * ####### or the class specified does not exist, then use 223 * If an entry with the recordid "me" does not exist, then use 224 * the default of LOGIN_DEFCLASS (ie. "default"). 225 * Return a filled-out login_cap_t structure, including 226 * class name, and the capability record buffer. | |
227 */ 228 229login_cap_t * 230login_getuserclass(const struct passwd *pwd) 231{ | 303 */ 304 305login_cap_t * 306login_getuserclass(const struct passwd *pwd) 307{ |
232 const char * class = "me"; /* (pwd == NULL) ? NULL : pwd->pw_class; */ 233 const char * home = (pwd == NULL) ? NULL : pwd->pw_dir; 234 return login_getclassbyname(class, home); | 308 return login_getclassbyname(LOGIN_MECLASS, pwd); |
235} 236 237 238 239/* 240 * login_getcapstr() 241 * Given a login_cap entry, and a capability name, return the 242 * value defined for that capability, a defualt if not found, or 243 * an error string on error. 244 */ 245 246char * 247login_getcapstr(login_cap_t *lc, const char *cap, char *def, char *error) 248{ | 309} 310 311 312 313/* 314 * login_getcapstr() 315 * Given a login_cap entry, and a capability name, return the 316 * value defined for that capability, a defualt if not found, or 317 * an error string on error. 318 */ 319 320char * 321login_getcapstr(login_cap_t *lc, const char *cap, char *def, char *error) 322{ |
249 char *res; 250 int ret; | 323 char *res; 324 int ret; |
251 | 325 |
252 if (lc == NULL || cap == NULL || lc->lc_cap == NULL || *cap == '\0') 253 return def; | 326 if (lc == NULL || cap == NULL || lc->lc_cap == NULL || *cap == '\0') 327 return def; |
254 | 328 |
255 if ((ret = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) { 256 return def; 257 } else if (ret >= 0) 258 return res; 259 else 260 return error; | 329 if ((ret = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) 330 return def; 331 return (ret >= 0) ? res : error; |
261} 262 263 264/* 265 * login_getcaplist() 266 * Given a login_cap entry, and a capability name, return the 267 * value defined for that capability split into an array of 268 * strings. 269 */ 270 271char ** | 332} 333 334 335/* 336 * login_getcaplist() 337 * Given a login_cap entry, and a capability name, return the 338 * value defined for that capability split into an array of 339 * strings. 340 */ 341 342char ** |
272login_getcaplist(login_cap_t *lc, const char * cap, const char * chars) | 343login_getcaplist(login_cap_t *lc, const char *cap, const char *chars) |
273{ | 344{ |
274 char * lstring; | 345 char *lstring; |
275 | 346 |
276 if (chars == NULL) 277 chars = ", \t"; 278 if ((lstring = login_getcapstr(lc, (char*)cap, NULL, NULL)) != NULL) 279 return arrayize(lstring, chars, NULL); 280 return NULL; | 347 if (chars == NULL) 348 chars = ", \t"; 349 if ((lstring = login_getcapstr(lc, (char*)cap, NULL, NULL)) != NULL) 350 return arrayize(lstring, chars, NULL); 351 return NULL; |
281} 282 283 284/* 285 * login_getpath() 286 * From the login_cap_t <lc>, get the capability <cap> which is 287 * formatted as either a space or comma delimited list of paths 288 * and append them all into a string and separate by semicolons. 289 * If there is an error of any kind, return <error>. 290 */ 291 292char * 293login_getpath(login_cap_t *lc, const char *cap, char * error) 294{ | 352} 353 354 355/* 356 * login_getpath() 357 * From the login_cap_t <lc>, get the capability <cap> which is 358 * formatted as either a space or comma delimited list of paths 359 * and append them all into a string and separate by semicolons. 360 * If there is an error of any kind, return <error>. 361 */ 362 363char * 364login_getpath(login_cap_t *lc, const char *cap, char * error) 365{ |
295 char *str = login_getcapstr(lc, (char*)cap, NULL, NULL); | 366 char *str; |
296 | 367 |
297 if (str == NULL) 298 str = error; 299 else { 300 char *ptr = str; | 368 if ((str = login_getcapstr(lc, (char*)cap, NULL, NULL)) == NULL) 369 str = error; 370 else { 371 char *ptr = str; |
301 | 372 |
302 while (*ptr) { 303 int count = strcspn(ptr, ", \t"); 304 ptr += count; 305 if (*ptr) 306 *ptr++ = ':'; | 373 while (*ptr) { 374 int count = strcspn(ptr, ", \t"); 375 ptr += count; 376 if (*ptr) 377 *ptr++ = ':'; 378 } |
307 } | 379 } |
308 } 309 return str; | 380 return str; |
310} 311 312 | 381} 382 383 |
384static int 385isinfinite(const char *s) 386{ 387 static const char *infs[] = { 388 "infinity", 389 "inf", 390 "unlimited", 391 "unlimit", 392 "-1", 393 NULL 394 }; 395 const char **i = &infs[0]; 396 397 while (*i != NULL) { 398 if (strcasecmp(s, *i) == 0) 399 return 1; 400 ++i; 401 } 402 return 0; 403} 404 405 406static u_quad_t 407rmultiply(u_quad_t n1, u_quad_t n2) 408{ 409 u_quad_t m, r; 410 int b1, b2; 411 412 static int bpw = 0; 413 414 /* Handle simple cases */ 415 if (n1 == 0 || n2 == 0) 416 return 0; 417 if (n1 == 1) 418 return n2; 419 if (n2 == 1) 420 return n1; 421 422 /* 423 * sizeof() returns number of bytes needed for storage. 424 * This may be different from the actual number of useful bits. 425 */ 426 if (!bpw) { 427 bpw = sizeof(u_quad_t) * 8; 428 while (((u_quad_t)1 << (bpw-1)) == 0) 429 --bpw; 430 } 431 432 /* 433 * First check the magnitude of each number. If the sum of the 434 * magnatude is way to high, reject the number. (If this test 435 * is not done then the first multiply below may overflow.) 436 */ 437 for (b1 = bpw; (((u_quad_t)1 << (b1-1)) & n1) == 0; --b1) 438 ; 439 for (b2 = bpw; (((u_quad_t)1 << (b2-1)) & n2) == 0; --b2) 440 ; 441 if (b1 + b2 - 2 > bpw) { 442 errno = ERANGE; 443 return (UQUAD_MAX); 444 } 445 446 /* 447 * Decompose the multiplication to be: 448 * h1 = n1 & ~1 449 * h2 = n2 & ~1 450 * l1 = n1 & 1 451 * l2 = n2 & 1 452 * (h1 + l1) * (h2 + l2) 453 * (h1 * h2) + (h1 * l2) + (l1 * h2) + (l1 * l2) 454 * 455 * Since h1 && h2 do not have the low bit set, we can then say: 456 * 457 * (h1>>1 * h2>>1 * 4) + ... 458 * 459 * So if (h1>>1 * h2>>1) > (1<<(bpw - 2)) then the result will 460 * overflow. 461 * 462 * Finally, if MAX - ((h1 * l2) + (l1 * h2) + (l1 * l2)) < (h1*h2) 463 * then adding in residual amout will cause an overflow. 464 */ 465 466 m = (n1 >> 1) * (n2 >> 1); 467 if (m >= ((u_quad_t)1 << (bpw-2))) { 468 errno = ERANGE; 469 return (UQUAD_MAX); 470 } 471 m *= 4; 472 473 r = (n1 & n2 & 1) 474 + (n2 & 1) * (n1 & ~(u_quad_t)1) 475 + (n1 & 1) * (n2 & ~(u_quad_t)1); 476 477 if ((u_quad_t)(m + r) < m) { 478 errno = ERANGE; 479 return (UQUAD_MAX); 480 } 481 m += r; 482 483 return (m); 484} 485 486 |
|
313/* 314 * login_getcaptime() 315 * From the login_cap_t <lc>, get the capability <cap>, which is 316 * formatted as a time (e.g., "<cap>=10h3m2s"). If <cap> is not 317 * present in <lc>, return <def>; if there is an error of some kind, 318 * return <error>. 319 */ 320 321rlim_t 322login_getcaptime(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) 323{ | 487/* 488 * login_getcaptime() 489 * From the login_cap_t <lc>, get the capability <cap>, which is 490 * formatted as a time (e.g., "<cap>=10h3m2s"). If <cap> is not 491 * present in <lc>, return <def>; if there is an error of some kind, 492 * return <error>. 493 */ 494 495rlim_t 496login_getcaptime(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) 497{ |
324 char *res, *ep; 325 int ret; 326 rlim_t tot; | 498 char *res, *ep, *oval; 499 int r; 500 rlim_t tot; |
327 | 501 |
328 errno = 0; 329 if (lc == NULL || lc->lc_cap == NULL) 330 return def; | 502 errno = 0; 503 if (lc == NULL || lc->lc_cap == NULL) 504 return def; |
331 | 505 |
332 /* 333 * Look for 334 * If it's not there (-1), return 335 * If there's an error, return 336 */ | 506 /* 507 * Look for <cap> in lc_cap. 508 * If it's not there (-1), return <def>. 509 * If there's an error, return <error>. 510 */ |
337 | 511 |
338 if ((ret = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) 339 return def; 340 else if (ret < 0) 341 return error; | 512 if ((r = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) 513 return def; 514 else if (r < 0) { 515 errno = ERANGE; 516 return error; 517 } |
342 | 518 |
343 /* 344 * "inf" and "infinity" are two special cases for this. 345 */ 346 if (!strcasecmp(res, "infinity") || !strcasecmp(res, "inf")) 347 return RLIM_INFINITY; | 519 /* "inf" and "infinity" are special cases */ 520 if (isinfinite(res)) 521 return RLIM_INFINITY; |
348 | 522 |
349 /* 350 * Now go through the string, turning something like 1h2m3s into 351 * an integral value. Whee. 352 */ | 523 /* 524 * Now go through the string, turning something like 1h2m3s into 525 * an integral value. Whee. 526 */ |
353 | 527 |
354 errno = 0; 355 tot = 0; 356 while (*res) { 357 rlim_t tim = STRTOV(res, &ep, 0); 358 if ((ep == NULL) || (ep == res) || errno) { 359 return error; | 528 errno = 0; 529 tot = 0; 530 oval = res; 531 while (*res) { 532 rlim_t tim = strtoq(res, &ep, 0); 533 rlim_t mult = 1; 534 535 if (ep == NULL || ep == res || errno != 0) { 536 invalid: 537 syslog(LOG_WARNING, "login_getcaptime: class '%s' bad value %s=%s", 538 lc->lc_class, cap, oval); 539 errno = ERANGE; 540 return error; 541 } 542 /* Look for suffixes */ 543 switch (*ep++) { 544 case 0: 545 ep--; 546 break; /* end of string */ 547 case 's': case 'S': /* seconds */ 548 break; 549 case 'm': case 'M': /* minutes */ 550 mult = 60; 551 break; 552 case 'h': case 'H': /* hours */ 553 mult = 60L * 60L; 554 break; 555 case 'd': case 'D': /* days */ 556 mult = 60L * 60L * 24L; 557 break; 558 case 'w': case 'W': /* weeks */ 559 mult = 60L * 60L * 24L * 7L; 560 case 'y': case 'Y': /* 365-day years */ 561 mult = 60L * 60L * 24L * 365L; 562 default: 563 goto invalid; 564 } 565 res = ep; 566 tot += rmultiply(tim, mult); 567 if (errno) 568 goto invalid; |
360 } | 569 } |
361 /* Look for suffixes */ 362 switch (*ep++) { 363 case 0: 364 ep--; break; /* end of string */ 365 case 's': case 'S': /* seconds */ 366 break; 367 case 'm': case 'M': /* minutes */ 368 tim *= 60L; 369 break; 370 case 'h': case 'H': /* hours */ 371 tim *= (60L * 60L); 372 break; 373 case 'd': case 'D': /* days */ 374 tim *= (60L * 60L * 24L); 375 break; 376 case 'w': case 'W': /* weeks */ 377 tim *= (60L * 60L * 24L * 7L); 378 case 'y': case 'Y': /* Years */ 379 /* I refuse to take leap years into account here. Sue me. */ 380 tim *= (60L * 60L * 24L * 365L); 381 default: 382 return error; 383 } 384 res = ep; 385 tot += tim; 386 } 387 return tot; | 570 571 return tot; |
388} 389 390 391/* 392 * login_getcapnum() 393 * From the login_cap_t <lc>, extract the numerical value <cap>. 394 * If it is not present, return <def> for a default, and return 395 * <error> if there is an error. 396 * Like login_getcaptime(), only it only converts to a number, not 397 * to a time; "infinity" and "inf" are 'special.' 398 */ 399 400rlim_t 401login_getcapnum(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) 402{ | 572} 573 574 575/* 576 * login_getcapnum() 577 * From the login_cap_t <lc>, extract the numerical value <cap>. 578 * If it is not present, return <def> for a default, and return 579 * <error> if there is an error. 580 * Like login_getcaptime(), only it only converts to a number, not 581 * to a time; "infinity" and "inf" are 'special.' 582 */ 583 584rlim_t 585login_getcapnum(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) 586{ |
403 char *ep, *res; 404 int ret; 405 rlim_t val; | 587 char *ep, *res; 588 int r; 589 rlim_t val; |
406 | 590 |
407 if (lc == NULL || lc->lc_cap == NULL) 408 return def; | 591 if (lc == NULL || lc->lc_cap == NULL) 592 return def; |
409 | 593 |
410 /* 411 * For BSDI compatibility, try for the tag=<val> first 412 */ 413 if ((ret = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) { 414 long lval; | |
415 /* | 594 /* |
416 * String capability not present, so try for tag#<val> as numeric | 595 * For BSDI compatibility, try for the tag=<val> first |
417 */ | 596 */ |
418 if ((ret = cgetnum(lc->lc_cap, (char *)cap, &lval)) == -1) 419 return def; /* Not there, so return default */ 420 else if (ret < 0) 421 return error; 422 return (rlim_t)lval; 423 } 424 else if (ret < 0) 425 return error; | 597 if ((r = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) { 598 long lval; 599 /* string capability not present, so try for tag#<val> as numeric */ 600 if ((r = cgetnum(lc->lc_cap, (char *)cap, &lval)) == -1) 601 return def; /* Not there, so return default */ 602 else if (r >= 0) 603 return (rlim_t)lval; 604 } |
426 | 605 |
427 if (!strcasecmp(res, "infinity") || !strcasecmp(res, "inf")) 428 return RLIM_INFINITY; | 606 if (r < 0) { 607 errno = ERANGE; 608 return error; 609 } |
429 | 610 |
430 errno = 0; 431 val = STRTOV(res, &ep, 0); 432 if ((ep == NULL) || (ep == res) || errno) 433 return error; 434 return val; | 611 if (isinfinite(res)) 612 return RLIM_INFINITY; 613 614 errno = 0; 615 val = strtoq(res, &ep, 0); 616 if (ep == NULL || ep == res || errno != 0) { 617 syslog(LOG_WARNING, "login_getcapnum: class '%s' bad value %s=%s", 618 lc->lc_class, cap, res); 619 errno = ERANGE; 620 return error; 621 } 622 623 return val; |
435} 436 437 | 624} 625 626 |
627 |
|
438/* 439 * login_getcapsize() 440 * From the login_cap_t <lc>, extract the capability <cap>, which is 441 * formatted as a size (e.g., "<cap>=10M"); it can also be "infinity". 442 * If not present, return <def>, or <error> if there is an error of 443 * some sort. 444 */ 445 446rlim_t | 628/* 629 * login_getcapsize() 630 * From the login_cap_t <lc>, extract the capability <cap>, which is 631 * formatted as a size (e.g., "<cap>=10M"); it can also be "infinity". 632 * If not present, return <def>, or <error> if there is an error of 633 * some sort. 634 */ 635 636rlim_t |
447login_getcapsize(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) { 448 char *ep, *res; 449 int ret; 450 rlim_t tot, mult; | 637login_getcapsize(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error) 638{ 639 char *ep, *res, *oval; 640 int r; 641 rlim_t tot; |
451 | 642 |
452 if (lc == NULL || lc->lc_cap == NULL) 453 return def; | 643 if (lc == NULL || lc->lc_cap == NULL) 644 return def; |
454 | 645 |
455 if ((ret = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) 456 return def; 457 else if (ret < 0) 458 return error; | 646 if ((r = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) 647 return def; 648 else if (r < 0) { 649 errno = ERANGE; 650 return error; 651 } |
459 | 652 |
460 /* 461 * "inf" and "infinity" are two special cases for this. 462 */ 463 if (!strcasecmp(res, "infinity") || !strcasecmp(res, "inf")) 464 return RLIM_INFINITY; | 653 if (isinfinite(res)) 654 return RLIM_INFINITY; |
465 | 655 |
466 errno = 0; 467 tot = 0; 468 while (*res) { 469 rlim_t val = STRTOV(res, &ep, 0); 470 if ((res == NULL) || (res == ep) || errno) 471 return error; 472 switch (*ep++) { 473 case 0: /* end of string */ 474 ep--; 475 mult = 1; 476 break; 477 case 'b': case 'B': /* 512-byte blocks */ 478 mult = 512; break; 479 case 'k': case 'K': /* 1024-byte Kilobytes */ 480 mult = 1024; break; 481 case 'm': case 'M': /* 1024-k kbytes */ 482 mult = 1024 * 1024; break; 483 case 'g': case 'G': /* 1Gbyte */ 484 mult = 1024 * 1024 * 1024; break; 485#ifndef RLIM_LONG 486 case 't': case 'T': /* 1TBte */ 487 mult = 1024LL * 1024LL * 1024LL * 1024LL; break; 488#endif 489 default: 490 return error; | 656 errno = 0; 657 tot = 0; 658 oval = res; 659 while (*res) { 660 rlim_t siz = strtoq(res, &ep, 0); 661 rlim_t mult = 1; 662 663 if (ep == NULL || ep == res || errno != 0) { 664 invalid: 665 syslog(LOG_WARNING, "login_getcapsize: class '%s' bad value %s=%s", 666 lc->lc_class, cap, oval); 667 errno = ERANGE; 668 return error; 669 } 670 switch (*ep++) { 671 case 0: /* end of string */ 672 ep--; 673 break; 674 case 'b': case 'B': /* 512-byte blocks */ 675 mult = 512; 676 break; 677 case 'k': case 'K': /* 1024-byte Kilobytes */ 678 mult = 1024; 679 break; 680 case 'm': case 'M': /* 1024-k kbytes */ 681 mult = 1024 * 1024; 682 break; 683 case 'g': case 'G': /* 1Gbyte */ 684 mult = 1024 * 1024 * 1024; 685 break; 686 case 't': case 'T': /* 1TBte */ 687 mult = 1024LL * 1024LL * 1024LL * 1024LL; 688 break; 689 default: 690 goto invalid; 691 } 692 res = ep; 693 tot += rmultiply(siz, mult); 694 if (errno) 695 goto invalid; |
491 } | 696 } |
492 res = ep; 493 tot += (val * mult); 494 } 495 return tot; | 697 698 return tot; |
496} 497 498 499/* 500 * login_getcapbool() 501 * From the login_cap_t <lc>, check for the existance of the capability 502 * of <cap>. Return <def> if <lc>->lc_cap is NULL, otherwise return 503 * the whether or not <cap> exists there. 504 */ 505 506int 507login_getcapbool(login_cap_t *lc, const char *cap, int def) 508{ | 699} 700 701 702/* 703 * login_getcapbool() 704 * From the login_cap_t <lc>, check for the existance of the capability 705 * of <cap>. Return <def> if <lc>->lc_cap is NULL, otherwise return 706 * the whether or not <cap> exists there. 707 */ 708 709int 710login_getcapbool(login_cap_t *lc, const char *cap, int def) 711{ |
509 if (lc == NULL || lc->lc_cap == NULL) 510 return def; 511 return (cgetcap(lc->lc_cap, (char *)cap, ':') != NULL); | 712 if (lc == NULL || lc->lc_cap == NULL) 713 return def; 714 return (cgetcap(lc->lc_cap, (char *)cap, ':') != NULL); |
512} 513 514 515/* 516 * login_getstyle() 517 * Given a login_cap entry <lc>, and optionally a type of auth <auth>, 518 * and optionally a style <style>, find the style that best suits these 519 * rules: --- 10 unchanged lines hidden (view full) --- 530 * login_getstyle(lc, NULL, "ftp"); 531 * login_getstyle(lc, "login", NULL); 532 * login_getstyle(lc, "skey", "network"); 533 */ 534 535char * 536login_getstyle(login_cap_t *lc, char *style, const char *auth) 537{ | 715} 716 717 718/* 719 * login_getstyle() 720 * Given a login_cap entry <lc>, and optionally a type of auth <auth>, 721 * and optionally a style <style>, find the style that best suits these 722 * rules: --- 10 unchanged lines hidden (view full) --- 733 * login_getstyle(lc, NULL, "ftp"); 734 * login_getstyle(lc, "login", NULL); 735 * login_getstyle(lc, "skey", "network"); 736 */ 737 738char * 739login_getstyle(login_cap_t *lc, char *style, const char *auth) 740{ |
538 int i; 539 char **authtypes = NULL; 540 char *auths= NULL; 541 char realauth[64]; | 741 int i; 742 char **authtypes = NULL; 743 char *auths= NULL; 744 char realauth[64]; |
542 | 745 |
543 static char *defauthtypes[] = { LOGIN_DEFSTYLE, NULL }; | 746 static char *defauthtypes[] = { LOGIN_DEFSTYLE, NULL }; |
544 | 747 |
545 if (auth != NULL && *auth != '\0' && 546 snprintf(realauth, sizeof realauth, "auth-%s", auth) < sizeof realauth) 547 authtypes = login_getcaplist(lc, realauth, NULL); | 748 if (auth != NULL && *auth != '\0') { 749 if (snprintf(realauth, sizeof realauth, "auth-%s", auth) < sizeof realauth) 750 authtypes = login_getcaplist(lc, realauth, NULL); 751 } |
548 | 752 |
549 if (authtypes == NULL) 550 authtypes = login_getcaplist(lc, "auth", NULL); | 753 if (authtypes == NULL) 754 authtypes = login_getcaplist(lc, "auth", NULL); |
551 | 755 |
552 if (authtypes == NULL) 553 authtypes = defauthtypes; | 756 if (authtypes == NULL) 757 authtypes = defauthtypes; |
554 | 758 |
555 /* 556 * We have at least one authtype now; auths is a comma-seperated 557 * (or space-separated) list of authentication types. We have to 558 * convert from this to an array of char*'s; authtypes then gets this. 559 */ 560 i = 0; 561 if (style != NULL && *style != '\0') { 562 while (authtypes[i] != NULL && strcmp(style, authtypes[i]) != 0) 563 i++; 564 } 565 lc->lc_style = NULL; 566 if (authtypes[i] != NULL && (auths = strdup(authtypes[i])) != NULL) 567 lc->lc_style = auths; | 759 /* 760 * We have at least one authtype now; auths is a comma-seperated 761 * (or space-separated) list of authentication types. We have to 762 * convert from this to an array of char*'s; authtypes then gets this. 763 */ 764 i = 0; 765 if (style != NULL && *style != '\0') { 766 while (authtypes[i] != NULL && strcmp(style, authtypes[i]) != 0) 767 i++; 768 } |
568 | 769 |
569 return lc->lc_style; 570} | 770 lc->lc_style = NULL; 771 if (authtypes[i] != NULL && (auths = strdup(authtypes[i])) != NULL) 772 lc->lc_style = auths; |
571 | 773 |
774 if (lc->lc_style != NULL) 775 lc->lc_style = strdup(lc->lc_style); |
|
572 | 776 |
777 return lc->lc_style; 778} |
|