Possibly negotiate authentication with the client. Use "leader" to * start off the auth if necessary. * * Return NULL if authentication failed. Return "" if anonymous access. * Otherwise return username. */
| 223 | * Otherwise return username. |
| 224 | */ |
| 225 | char *auth_server(int f_in, int f_out, int module, const char *host, |
| 226 | const char *addr, const char *leader) |
| 227 | { |
| 228 | char *users = lp_auth_users(module); |
| 229 | char challenge[MAX_DIGEST_LEN*2]; |
| 230 | char line[BIGPATHBUFLEN]; |
| 231 | const char **auth_uid_groups = NULL; |
| 232 | int auth_uid_groups_cnt = -1; |
| 233 | const char *err = NULL; |
| 234 | int group_match = -1; |
| 235 | char *tok, *pass; |
| 236 | char opt_ch = '\0'; |
| 237 | |
| 238 | /* if no auth list then allow anyone in! */ |
| 239 | if (!users || !*users) |
| 240 | return ""; |
| 241 | |
| 242 | negotiate_daemon_auth(f_out, 0); |
| 243 | gen_challenge(addr, challenge); |
| 244 | |
| 245 | io_printf(f_out, "%s%s\n", leader, challenge); |
| 246 | |
| 247 | if (!read_line_old(f_in, line, sizeof line, 0) |
| 248 | || (pass = strchr(line, ' ')) == NULL) { |
| 249 | rprintf(FLOG, "auth failed on module %s from %s (%s): " |
| 250 | "invalid challenge response\n", |
| 251 | lp_name(module), host, addr); |
| 252 | return NULL; |
| 253 | } |
| 254 | *pass++ = '\0'; |
| 255 | |
| 256 | users = strdup(users); |
| 257 | |
| 258 | for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) { |
| 259 | char *opts; |
| 260 | /* See if the user appended :deny, :ro, or :rw. */ |
| 261 | if ((opts = strchr(tok, ':')) != NULL) { |
| 262 | *opts++ = '\0'; |
| 263 | opt_ch = isUpper(opts) ? toLower(opts) : *opts; |
| 264 | if (opt_ch == 'r') { /* handle ro and rw */ |
| 265 | opt_ch = isUpper(opts+1) ? toLower(opts+1) : opts[1]; |
| 266 | if (opt_ch == 'o') |
| 267 | opt_ch = 'r'; |
| 268 | else if (opt_ch != 'w') |
| 269 | opt_ch = '\0'; |
| 270 | } else if (opt_ch != 'd') /* if it's not deny, ignore it */ |
| 271 | opt_ch = '\0'; |
| 272 | } else |
| 273 | opt_ch = '\0'; |
| 274 | if (*tok != '@') { |
| 275 | /* Match the username */ |
| 276 | if (wildmatch(tok, line)) |
| 277 | break; |
| 278 | } else { |
| 279 | #ifdef HAVE_GETGROUPLIST |
| 280 | int j; |
| 281 | /* See if authorizing user is a real user, and if so, see |
| 282 | * if it is in a group that matches tok+1 wildmat. */ |
no test coverage detected