Changeset 547 in openpam
- Timestamp:
- 04/01/12 15:01:21 (14 months ago)
- Location:
- trunk
- Files:
-
- 3 added
- 10 edited
-
CREDITS (modified) (1 diff)
-
doc/man (modified) (1 prop)
-
doc/man/Makefile.am (modified) (1 diff)
-
include/security/openpam.h (modified) (1 diff)
-
lib/Makefile.am (modified) (1 diff)
-
lib/openpam_configure.c (modified) (14 diffs)
-
lib/openpam_ctype.h (added)
-
lib/openpam_impl.h (modified) (1 diff)
-
lib/openpam_load.c (modified) (1 diff)
-
lib/openpam_readline.c (modified) (5 diffs)
-
lib/openpam_readlinev.c (added)
-
lib/openpam_readword.c (added)
-
lib/openpam_straddch.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/CREDITS
r526 r547 28 28 Juli Mallett <jmallett@freebsd.org> 29 29 Jörg Sonnenberger <joerg@britannica.bec.de> 30 Maëlle Lesage <lesage.maelle@gmail.com> 30 31 Mark Murray <markm@freebsd.org> 31 32 Matthias Drochner <drochner@netbsd.org> -
trunk/doc/man
- Property svn:ignore
-
old new 9 9 openpam_nullconv.3 10 10 openpam_readline.3 11 openpam_readlinev.3 12 openpam_readword.3 11 13 openpam_restore_cred.3 12 14 openpam_set_option.3 15 openpam_straddch.3 13 16 openpam_subst.3 14 17 openpam_ttyconv.3
-
- Property svn:ignore
-
trunk/doc/man/Makefile.am
r535 r547 43 43 openpam_nullconv.3 \ 44 44 openpam_readline.3 \ 45 openpam_readlinev.3 \ 46 openpam_readword.3 \ 45 47 openpam_restore_cred.3 \ 46 48 openpam_set_option.3 \ -
trunk/include/security/openpam.h
r535 r547 159 159 OPENPAM_NONNULL((1)); 160 160 161 char ** 162 openpam_readlinev(FILE *_f, 163 int *_lineno, 164 int *_lenp) 165 OPENPAM_NONNULL((1)); 166 167 char * 168 openpam_readword(FILE *_f, 169 int *_lineno, 170 size_t *_lenp) 171 OPENPAM_NONNULL((1)); 172 #endif 173 161 174 int 162 175 openpam_straddch(char **_str, 163 size_t *_sizep,164 size_t *_lenp,165 int ch); 166 #endif 176 size_t *_sizep, 177 size_t *_lenp, 178 int ch) 179 OPENPAM_NONNULL((1)); 167 180 168 181 /* -
trunk/lib/Makefile.am
r528 r547 29 29 openpam_nullconv.c \ 30 30 openpam_readline.c \ 31 openpam_readlinev.c \ 32 openpam_readword.c \ 31 33 openpam_restore_cred.c \ 32 34 openpam_set_option.c \ -
trunk/lib/openpam_configure.c
r524 r547 1 1 /*- 2 2 * Copyright (c) 2001-2003 Networks Associates Technology, Inc. 3 * Copyright (c) 2004-201 1Dag-Erling Smørgrav3 * Copyright (c) 2004-2012 Dag-Erling Smørgrav 4 4 * All rights reserved. 5 5 * … … 51 51 52 52 #include "openpam_impl.h" 53 #include "openpam_ctype.h" 53 54 #include "openpam_strlcmp.h" 54 55 … … 56 57 57 58 /* 58 * Evaluates to non-zero if the argument is a linear whitespace character. 59 */ 60 #define is_lws(ch) \ 61 (ch == ' ' || ch == '\t') 62 63 /* 64 * Evaluates to non-zero if the argument is a printable ASCII character. 65 * Assumes that the execution character set is a superset of ASCII. 66 */ 67 #define is_p(ch) \ 68 (ch >= '!' && ch <= '~') 69 70 /* 71 * Returns non-zero if the argument belongs to the POSIX Portable Filename 72 * Character Set. Assumes that the execution character set is a superset 73 * of ASCII. 74 */ 75 #define is_pfcs(ch) \ 76 ((ch >= '0' && ch <= '9') || \ 77 (ch >= 'A' && ch <= 'Z') || \ 78 (ch >= 'a' && ch <= 'z') || \ 79 ch == '.' || ch == '_' || ch == '-') 80 81 /* 82 * Parse the service name. 83 * 84 * Returns the length of the service name, or 0 if the end of the string 85 * was reached or a disallowed non-whitespace character was encountered. 86 * 87 * If parse_service_name() is successful, it updates *service to point to 88 * the first character of the service name and *line to point one 89 * character past the end. If it reaches the end of the string, it 90 * updates *line to point to the terminating NUL character and leaves 91 * *service unmodified. In all other cases, it leaves both *line and 92 * *service unmodified. 93 * 94 * Allowed characters are all characters in the POSIX portable filename 95 * character set. 59 * Validate a service name. 60 * 61 * Returns a non-zero value if the argument points to a NUL-terminated 62 * string consisting entirely of characters in the POSIX portable filename 63 * character set, excluding the path separator character. 96 64 */ 97 65 static int 98 parse_service_name(char **line, char **service) 99 { 100 char *b, *e; 101 102 for (b = *line; *b && is_lws(*b); ++b) 103 /* nothing */ ; 104 if (!*b) { 105 *line = b; 106 return (0); 107 } 108 for (e = b; *e && !is_lws(*e); ++e) 109 if (!is_pfcs(*e)) 66 valid_service_name(const char *name) 67 { 68 const char *p; 69 70 for (p = name; *p != '\0'; ++p) 71 if (!is_pfcs(*p)) 110 72 return (0); 111 if (e == b) 112 return (0); 113 *line = e; 114 *service = b; 115 return (e - b); 73 return (1); 116 74 } 117 75 … … 119 77 * Parse the facility name. 120 78 * 121 * Returns the corresponding pam_facility_t value, or -1 if the end of the 122 * string was reached, a disallowed non-whitespace character was 123 * encountered, or the first word was not a recognized facility name. 124 * 125 * If parse_facility_name() is successful, it updates *line to point one 126 * character past the end of the facility name. If it reaches the end of 127 * the string, it updates *line to point to the terminating NUL character. 128 * In all other cases, it leaves *line unmodified. 79 * Returns the corresponding pam_facility_t value, or -1 if the argument 80 * is not a valid facility name. 129 81 */ 130 82 static pam_facility_t 131 parse_facility_name(char **line) 132 { 133 char *b, *e; 83 parse_facility_name(const char *name) 84 { 134 85 int i; 135 86 136 for (b = *line; *b && is_lws(*b); ++b)137 /* nothing */ ;138 if (!*b) {139 *line = b;140 return ((pam_facility_t)-1);141 }142 for (e = b; *e && !is_lws(*e); ++e)143 /* nothing */ ;144 if (e == b)145 return ((pam_facility_t)-1);146 87 for (i = 0; i < PAM_NUM_FACILITIES; ++i) 147 if (strlcmp(pam_facility_name[i], b, e - b) == 0) 148 break; 149 if (i == PAM_NUM_FACILITIES) 150 return ((pam_facility_t)-1); 151 *line = e; 152 return (i); 153 } 154 155 /* 156 * Parse the word "include". 157 * 158 * If the next word on the line is "include", parse_include() updates 159 * *line to point one character past "include" and returns 1. Otherwise, 160 * it leaves *line unmodified and returns 0. 88 if (strcmp(pam_facility_name[i], name) == 0) 89 return (i); 90 return ((pam_facility_t)-1); 91 } 92 93 /* 94 * Parse the control flag. 95 * 96 * Returns the corresponding pam_control_t value, or -1 if the argument is 97 * not a valid control flag name. 98 */ 99 static pam_control_t 100 parse_control_flag(const char *name) 101 { 102 int i; 103 104 for (i = 0; i < PAM_NUM_CONTROL_FLAGS; ++i) 105 if (strcmp(pam_control_flag_name[i], name) == 0) 106 return (i); 107 return ((pam_control_t)-1); 108 } 109 110 /* 111 * Validate a file name. 112 * 113 * Returns a non-zero value if the argument points to a NUL-terminated 114 * string consisting entirely of characters in the POSIX portable filename 115 * character set, including the path separator character. 161 116 */ 162 117 static int 163 parse_include(char **line) 164 { 165 char *b, *e; 166 167 for (b = *line; *b && is_lws(*b); ++b) 168 /* nothing */ ; 169 if (!*b) { 170 *line = b; 171 return (-1); 172 } 173 for (e = b; *e && !is_lws(*e); ++e) 174 /* nothing */ ; 175 if (e == b) 176 return (0); 177 if (strlcmp("include", b, e - b) != 0) 178 return (0); 179 *line = e; 118 valid_filename(const char *name) 119 { 120 const char *p; 121 122 for (p = name; *p != '\0'; ++p) 123 if (!is_pfcs(*p) && *p != '/') 124 return (0); 180 125 return (1); 181 }182 183 /*184 * Parse the control flag.185 *186 * Returns the corresponding pam_control_t value, or -1 if the end of the187 * string was reached, a disallowed non-whitespace character was188 * encountered, or the first word was not a recognized control flag.189 *190 * If parse_control_flag() is successful, it updates *line to point one191 * character past the end of the control flag. If it reaches the end of192 * the string, it updates *line to point to the terminating NUL character.193 * In all other cases, it leaves *line unmodified.194 */195 static pam_control_t196 parse_control_flag(char **line)197 {198 char *b, *e;199 int i;200 201 for (b = *line; *b && is_lws(*b); ++b)202 /* nothing */ ;203 if (!*b) {204 *line = b;205 return ((pam_control_t)-1);206 }207 for (e = b; *e && !is_lws(*e); ++e)208 /* nothing */ ;209 if (e == b)210 return ((pam_control_t)-1);211 for (i = 0; i < PAM_NUM_CONTROL_FLAGS; ++i)212 if (strlcmp(pam_control_flag_name[i], b, e - b) == 0)213 break;214 if (i == PAM_NUM_CONTROL_FLAGS)215 return ((pam_control_t)-1);216 *line = e;217 return (i);218 }219 220 /*221 * Parse a file name.222 *223 * Returns the length of the file name, or 0 if the end of the string was224 * reached or a disallowed non-whitespace character was encountered.225 *226 * If parse_filename() is successful, it updates *filename to point to the227 * first character of the filename and *line to point one character past228 * the end. If it reaches the end of the string, it updates *line to229 * point to the terminating NUL character and leaves *filename unmodified.230 * In all other cases, it leaves both *line and *filename unmodified.231 *232 * Allowed characters are all characters in the POSIX portable filename233 * character set, plus the path separator (forward slash).234 */235 static int236 parse_filename(char **line, char **filename)237 {238 char *b, *e;239 240 for (b = *line; *b && is_lws(*b); ++b)241 /* nothing */ ;242 if (!*b) {243 *line = b;244 return (0);245 }246 for (e = b; *e && !is_lws(*e); ++e)247 if (!is_pfcs(*e) && *e != '/')248 return (0);249 if (e == b)250 return (0);251 *line = e;252 *filename = b;253 return (e - b);254 }255 256 /*257 * Parse an option.258 *259 * Returns a dynamically allocated string containing the next module260 * option, or NULL if the end of the string was reached or a disallowed261 * non-whitespace character was encountered.262 *263 * If parse_option() is successful, it updates *line to point one264 * character past the end of the option. If it reaches the end of the265 * string, it updates *line to point to the terminating NUL character. In266 * all other cases, it leaves *line unmodified.267 *268 * If parse_option() fails to allocate memory, it will return NULL and set269 * errno to a non-zero value.270 *271 * Allowed characters for option names are all characters in the POSIX272 * portable filename character set. Allowed characters for option values273 * are any printable non-whitespace characters. The option value may be274 * quoted in either single or double quotes, in which case space275 * characters and whichever quote character was not used are allowed.276 * Note that the entire value must be quoted, not just part of it.277 */278 static char *279 parse_option(char **line)280 {281 char *nb, *ne, *vb, *ve;282 unsigned char q = 0;283 char *option;284 size_t size;285 286 errno = 0;287 for (nb = *line; *nb && is_lws(*nb); ++nb)288 /* nothing */ ;289 if (!*nb) {290 *line = nb;291 return (NULL);292 }293 for (ne = nb; *ne && !is_lws(*ne) && *ne != '='; ++ne)294 if (!is_pfcs(*ne))295 return (NULL);296 if (ne == nb)297 return (NULL);298 if (*ne == '=') {299 vb = ne + 1;300 if (*vb == '"' || *vb == '\'')301 q = *vb++;302 for (ve = vb;303 *ve && *ve != q && (is_p(*ve) || (q && is_lws(*ve)));304 ++ve)305 /* nothing */ ;306 if (q && *ve != q)307 /* non-printable character or missing endquote */308 return (NULL);309 if (q && *(ve + 1) && !is_lws(*(ve + 1)))310 /* garbage after value */311 return (NULL);312 } else {313 vb = ve = ne;314 }315 size = (ne - nb) + 1;316 if (ve > vb)317 size += (ve - vb) + 1;318 if ((option = malloc(size)) == NULL)319 return (NULL);320 strncpy(option, nb, ne - nb);321 if (ve > vb) {322 option[ne - nb] = '=';323 strncpy(option + (ne - nb) + 1, vb, ve - vb);324 }325 option[size - 1] = '\0';326 *line = q ? ve + 1 : ve;327 return (option);328 }329 330 /*331 * Consume trailing whitespace.332 *333 * If there are no non-whitespace characters left on the line, parse_eol()334 * updates *line to point at the terminating NUL character and returns 0.335 * Otherwise, it leaves *line unmodified and returns a non-zero value.336 */337 static int338 parse_eol(char **line)339 {340 char *p;341 342 for (p = *line; *p && is_lws(*p); ++p)343 /* nothing */ ;344 if (*p)345 return ((unsigned char)*p);346 *line = p;347 return (0);348 126 } 349 127 … … 368 146 pam_facility_t fclt; 369 147 pam_control_t ctlf; 370 char *line, *str, *name; 371 char *option, **optv; 372 int count, len, lineno, ret, serrno; 148 char *name, *servicename, *modulename; 149 int count, lineno, ret, serrno; 150 char **wordv, *word; 151 int i, wordc; 373 152 374 153 count = 0; … … 376 155 name = NULL; 377 156 lineno = 0; 378 while ((line = openpam_readline(f, &lineno, NULL)) != NULL) { 379 /* get service name if necessary */ 380 if (style == pam_conf_style) { 381 if ((len = parse_service_name(&line, &str)) == 0) { 382 openpam_log(PAM_LOG_NOTICE, 383 "%s(%d): invalid service name (ignored)", 384 filename, lineno); 385 FREE(line); 386 continue; 387 } 388 if (strlcmp(service, str, len) != 0) { 389 FREE(line); 390 continue; 391 } 392 } 393 394 /* get facility name */ 395 if ((fclt = parse_facility_name(&line)) == (pam_facility_t)-1) { 157 wordc = 0; 158 wordv = NULL; 159 while ((wordv = openpam_readlinev(f, &lineno, &wordc)) != NULL) { 160 /* blank line? */ 161 if (wordc == 0) { 162 FREEV(wordc, wordv); 163 continue; 164 } 165 i = 0; 166 167 /* check service name if necessary */ 168 if (style == pam_conf_style && 169 strcmp(wordv[i++], service) != 0) { 170 FREEV(wordc, wordv); 171 continue; 172 } 173 174 /* check facility name */ 175 if ((word = wordv[i++]) == NULL || 176 (fclt = parse_facility_name(word)) == (pam_facility_t)-1) { 396 177 openpam_log(PAM_LOG_ERROR, 397 178 "%s(%d): missing or invalid facility", … … 400 181 } 401 182 if (facility != fclt && facility != PAM_FACILITY_ANY) { 402 FREE (line);183 FREEV(wordc, wordv); 403 184 continue; 404 185 } 405 186 406 187 /* check for "include" */ 407 if (parse_include(&line)) { 408 if ((len = parse_service_name(&line, &str)) == 0) { 188 if ((word = wordv[i++]) != NULL && 189 strcmp(word, "include") == 0) { 190 if ((servicename = wordv[i++]) == NULL || 191 !valid_service_name(servicename)) { 409 192 openpam_log(PAM_LOG_ERROR, 410 "%s(%d): missing or invalid filename",193 "%s(%d): missing or invalid service name", 411 194 filename, lineno); 412 195 goto fail; 413 196 } 414 if ((name = strndup(str, len)) == NULL) 415 goto syserr; 416 if (parse_eol(&line) != 0) { 197 if (wordv[i] != NULL) { 417 198 openpam_log(PAM_LOG_ERROR, 418 199 "%s(%d): garbage at end of line", … … 420 201 goto fail; 421 202 } 422 ret = openpam_load_chain(pamh, name, fclt);423 FREE (name);203 ret = openpam_load_chain(pamh, servicename, fclt); 204 FREEV(wordc, wordv); 424 205 if (ret < 0) 425 206 goto fail; 426 FREE(line);427 207 continue; 428 208 } 429 209 430 210 /* get control flag */ 431 if ((ctlf = parse_control_flag(&line)) == (pam_control_t)-1) { 211 if (word == NULL || /* same word we compared to "include" */ 212 (ctlf = parse_control_flag(word)) == (pam_control_t)-1) { 432 213 openpam_log(PAM_LOG_ERROR, 433 214 "%s(%d): missing or invalid control flag", … … 437 218 438 219 /* get module name */ 439 if ((len = parse_filename(&line, &str)) == 0) { 220 if ((modulename = wordv[i++]) == NULL || 221 !valid_filename(modulename)) { 440 222 openpam_log(PAM_LOG_ERROR, 441 223 "%s(%d): missing or invalid module name", … … 443 225 goto fail; 444 226 } 445 if ((name = strndup(str, len)) == NULL)446 goto syserr;447 227 448 228 /* allocate new entry */ … … 451 231 this->flag = ctlf; 452 232 453 /* get module options */ 454 if ((this->optv = malloc(sizeof *optv)) == NULL) 455 goto syserr; 456 this->optc = 0; 457 while ((option = parse_option(&line)) != NULL) { 458 optv = realloc(this->optv, 459 (this->optc + 2) * sizeof *optv); 460 if (optv == NULL) 461 goto syserr; 462 this->optv = optv; 463 this->optv[this->optc++] = option; 464 } 465 this->optv[this->optc] = NULL; 466 if (*line != '\0') { 467 openpam_log(PAM_LOG_ERROR, 468 "%s(%d): syntax error in module options", 469 filename, lineno); 233 /* load module */ 234 if ((this->module = openpam_load_module(modulename)) == NULL) 470 235 goto fail; 471 } 472 473 /* load module */ 474 this->module = openpam_load_module(name); 475 FREE(name); 476 if (this->module == NULL) 477 goto fail; 236 237 /* 238 * The remaining items in wordv are the module's 239 * arguments. We could set this->optv = wordv + i, but 240 * then free(this->optv) wouldn't work. Instead, we free 241 * the words we've already consumed, shift the rest up, 242 * and clear the tail end of the array. 243 */ 244 this->optc = wordc - i; 245 for (i = 0; i < wordc - this->optc; ++i) { 246 FREE(wordv[i]); 247 wordv[i] = wordv[wordc - this->optc + i]; 248 wordv[wordc - this->optc + i] = NULL; 249 } 250 this->optv = wordv; 251 wordv = NULL; 252 wordc = 0; 478 253 479 254 /* hook it up */ … … 484 259 this = NULL; 485 260 ++count; 486 487 /* next please... */488 FREE(line);489 261 } 262 /* 263 * The loop ended because openpam_readword() returned NULL, which 264 * can happen for four different reasons: an I/O error (ferror(f) 265 * is true), a memory allocation failure (ferror(f) is false, 266 * errno is non-zero) 267 */ 268 if (ferror(f) || errno != 0) 269 goto syserr; 490 270 if (!feof(f)) 491 goto syserr;271 goto fail; 492 272 fclose(f); 493 273 return (count); … … 499 279 fail: 500 280 serrno = errno; 501 if (this && this->optc) { 502 while (this->optc--) 503 FREE(this->optv[this->optc]); 504 FREE(this->optv); 505 } 281 if (this && this->optc && this->optv) 282 FREEV(this->optc, this->optv); 506 283 FREE(this); 507 FREE(line); 284 FREEV(wordc, wordv); 285 FREE(wordv); 508 286 FREE(name); 287 fclose(f); 509 288 errno = serrno; 510 289 return (-1); … … 539 318 int ret, serrno; 540 319 320 if (!valid_service_name(service)) { 321 openpam_log(PAM_LOG_ERROR, "invalid service name"); 322 errno = EINVAL; 323 RETURNN(-1); 324 } 541 325 ENTERS(facility < 0 ? "any" : pam_facility_name[facility]); 542 326 for (path = openpam_policy_path; *path != NULL; ++path) { -
trunk/lib/openpam_impl.h
r535 r547 158 158 pam_module_t *openpam_dynamic(const char *); 159 159 160 #define FREE(p) do { free((p)); (p) = NULL; } while (0) 160 #define FREE(p) \ 161 do { \ 162 free(p); \ 163 (p) = NULL; \ 164 } while (0) 165 166 #define FREEV(c, v) \ 167 do { \ 168 while (c) { \ 169 --(c); \ 170 FREE((v)[(c)]); \ 171 } \ 172 FREE(v); \ 173 } while (0) 161 174 162 175 #include "openpam_constants.h" -
trunk/lib/openpam_load.c
r491 r547 109 109 openpam_destroy_chain(chain->next); 110 110 chain->next = NULL; 111 while (chain->optc--) 112 FREE(chain->optv[chain->optc]); 113 FREE(chain->optv); 111 FREEV(chain->optc, chain->optv); 114 112 openpam_release_module(chain->module); 115 113 chain->module = NULL; -
trunk/lib/openpam_readline.c
r473 r547 45 45 46 46 #include <security/pam_appl.h> 47 47 48 #include "openpam_impl.h" 48 49 … … 62 63 int ch; 63 64 64 if ((line = malloc(MIN_LINE_LENGTH)) == NULL) 65 if ((line = malloc(size = MIN_LINE_LENGTH)) == NULL) { 66 openpam_log(PAM_LOG_ERROR, "malloc(): %m"); 65 67 return (NULL); 66 size = MIN_LINE_LENGTH;68 } 67 69 len = 0; 68 69 #define line_putch(ch) do { \70 if (len >= size - 1) { \71 char *tmp = realloc(line, size *= 2); \72 if (tmp == NULL) \73 goto fail; \74 line = tmp; \75 } \76 line[len++] = ch; \77 line[len] = '\0'; \78 } while (0)79 80 70 for (;;) { 81 71 ch = fgetc(f); … … 106 96 break; 107 97 } 108 /* whitespace */109 if (isspace(ch)) {110 /* ignore leading whitespace */111 /* collapse linear whitespace */112 if (len > 0 && line[len - 1] != ' ')113 line_putch(' ');114 continue;115 }116 98 /* anything else */ 117 line_putch(ch); 99 if (openpam_straddch(&line, &size, &len, ch) != 0) 100 goto fail; 118 101 } 119 120 /* remove trailing whitespace */121 while (len > 0 && isspace((unsigned char)line[len - 1]))122 --len;123 line[len] = '\0';124 102 if (len == 0) 125 103 goto fail; 126 104 if (lenp != NULL) 127 105 *lenp = len; 106 openpam_log(PAM_LOG_LIBDEBUG, "returning '%s'", line); 128 107 return (line); 129 108 fail: … … 134 113 /** 135 114 * The =openpam_readline function reads a line from a file, and returns it 136 * in a NUL-terminated buffer allocated with = malloc.115 * in a NUL-terminated buffer allocated with =!malloc. 137 116 * 138 117 * The =openpam_readline function performs a certain amount of processing 139 118 * on the data it reads: 140 119 * 141 * - Comments (introduced by a hash sign) are stripped, as is leading and 142 * trailing whitespace. 143 * - Any amount of linear whitespace is collapsed to a single space. 120 * - Comments (introduced by a hash sign) are stripped. 121 * 144 122 * - Blank lines are ignored. 123 * 145 124 * - If a line ends in a backslash, the backslash is stripped and the 146 125 * next line is appended. … … 153 132 * 154 133 * The caller is responsible for releasing the returned buffer by passing 155 * it to =free. 134 * it to =!free. 135 * 136 *>openpam_readlinev 137 *>openpam_readword 156 138 */ -
trunk/lib/openpam_straddch.c
r536 r547 12 12 * notice, this list of conditions and the following disclaimer in the 13 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote 15 * products derived from this software without specific prior written 16 * permission. 14 17 * 15 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND … … 32 35 #endif 33 36 37 #include <errno.h> 34 38 #include <stdlib.h> 35 39 … … 57 61 if ((tmpstr = malloc(tmpsize)) == NULL) { 58 62 openpam_log(PAM_LOG_ERROR, "malloc(): %m"); 63 errno = ENOMEM; 59 64 return (-1); 60 65 } … … 67 72 if ((tmpstr = realloc(*str, tmpsize)) == NULL) { 68 73 openpam_log(PAM_LOG_ERROR, "realloc(): %m"); 74 errno = ENOMEM; 69 75 return (-1); 70 76 } … … 100 106 * integer variable pointed to by =len and returns 0. 101 107 * Otherwise, it leaves the variables pointed to by =str, =size and =len 102 * unmodified and returns -1.108 * unmodified, sets :errno to =ENOMEM and returns -1. 103 109 */
Note: See TracChangeset
for help on using the changeset viewer.