1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License, Version 1.0 only 7 * (the "License"). You may not use this file except in compliance 8 * with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or https://opensource.org/licenses/CDDL-1.0. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 */ 23 /* 24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 29 30 #include "libuutil_common.h" 31 32 #include <string.h> 33 34 /* 35 * We require names of the form: 36 * [provider,]identifier[/[provider,]identifier]... 37 * 38 * Where provider is either a stock symbol (SUNW) or a java-style reversed 39 * domain name (com.sun). 40 * 41 * Both providers and identifiers must start with a letter, and may 42 * only contain alphanumerics, dashes, and underlines. Providers 43 * may also contain periods. 44 * 45 * Note that we do _not_ use the macros in <ctype.h>, since they are affected 46 * by the current locale settings. 47 */ 48 49 #define IS_ALPHA(c) \ 50 (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) 51 52 #define IS_DIGIT(c) \ 53 ((c) >= '0' && (c) <= '9') 54 55 static int 56 is_valid_ident(const char *s, const char *e, int allowdot) 57 { 58 char c; 59 60 if (s >= e) 61 return (0); /* name is empty */ 62 63 c = *s++; 64 if (!IS_ALPHA(c)) 65 return (0); /* does not start with letter */ 66 67 while (s < e && (c = *s++) != 0) { 68 if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' || 69 (allowdot && c == '.')) 70 continue; 71 return (0); /* invalid character */ 72 } 73 return (1); 74 } 75 76 static int 77 is_valid_component(const char *b, const char *e, uint_t flags) 78 { 79 char *sp; 80 81 if (flags & UU_NAME_DOMAIN) { 82 sp = strchr(b, ','); 83 if (sp != NULL && sp < e) { 84 if (!is_valid_ident(b, sp, 1)) 85 return (0); 86 b = sp + 1; 87 } 88 } 89 90 return (is_valid_ident(b, e, 0)); 91 } 92 93 int 94 uu_check_name(const char *name, uint_t flags) 95 { 96 const char *end = name + strlen(name); 97 const char *p; 98 99 if (flags & ~(UU_NAME_DOMAIN | UU_NAME_PATH)) { 100 uu_set_error(UU_ERROR_UNKNOWN_FLAG); 101 return (-1); 102 } 103 104 if (!(flags & UU_NAME_PATH)) { 105 if (!is_valid_component(name, end, flags)) 106 goto bad; 107 return (0); 108 } 109 110 while ((p = strchr(name, '/')) != NULL) { 111 if (!is_valid_component(name, p - 1, flags)) 112 goto bad; 113 name = p + 1; 114 } 115 if (!is_valid_component(name, end, flags)) 116 goto bad; 117 118 return (0); 119 120 bad: 121 uu_set_error(UU_ERROR_INVALID_ARGUMENT); 122 return (-1); 123 } 124