17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7257d1b4Sraf * Common Development and Distribution License (the "License"). 6*7257d1b4Sraf * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*7257d1b4Sraf 227c478bd9Sstevel@tonic-gate /* 23*7257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 30*7257d1b4Sraf #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 32*7257d1b4Sraf #include "lint.h" 337c478bd9Sstevel@tonic-gate #include <sys/types.h> 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate #include <signal.h> 367c478bd9Sstevel@tonic-gate #include <fcntl.h> 377c478bd9Sstevel@tonic-gate #include <unistd.h> 387c478bd9Sstevel@tonic-gate #include <shadow.h> 397c478bd9Sstevel@tonic-gate #include <errno.h> 407c478bd9Sstevel@tonic-gate #include <thread.h> 417c478bd9Sstevel@tonic-gate #include "mtlib.h" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #define LOCKFILE "/etc/.pwd.lock" 447c478bd9Sstevel@tonic-gate #define S_WAITTIME 15 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate static struct flock flock = { 477c478bd9Sstevel@tonic-gate 0, /* l_type */ 487c478bd9Sstevel@tonic-gate 0, /* l_whence */ 497c478bd9Sstevel@tonic-gate 0, /* l_start */ 507c478bd9Sstevel@tonic-gate 0, /* l_len */ 517c478bd9Sstevel@tonic-gate 0, /* l_sysid */ 527c478bd9Sstevel@tonic-gate 0 /* l_pid */ 537c478bd9Sstevel@tonic-gate }; 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* 567c478bd9Sstevel@tonic-gate * lckpwdf() returns a 0 for a successful lock within W_WAITTIME 577c478bd9Sstevel@tonic-gate * seconds and -1 otherwise. We stand on our head to make it MT-safe. 587c478bd9Sstevel@tonic-gate */ 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate static pid_t lck_pid = 0; /* process's pid at last lock */ 617c478bd9Sstevel@tonic-gate static thread_t lck_tid = 0; /* thread that holds the lock */ 627c478bd9Sstevel@tonic-gate static int fildes = -1; 637c478bd9Sstevel@tonic-gate static mutex_t lck_lock = DEFAULTMUTEX; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate int 667c478bd9Sstevel@tonic-gate lckpwdf(void) 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate int seconds = 0; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate lmutex_lock(&lck_lock); 717c478bd9Sstevel@tonic-gate for (;;) { 727c478bd9Sstevel@tonic-gate if (lck_pid != 0 && lck_pid != getpid()) { 737c478bd9Sstevel@tonic-gate /* somebody forked */ 747c478bd9Sstevel@tonic-gate lck_pid = 0; 757c478bd9Sstevel@tonic-gate lck_tid = 0; 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate if (lck_tid == 0) { 787c478bd9Sstevel@tonic-gate if ((fildes = creat(LOCKFILE, 0600)) == -1) 797c478bd9Sstevel@tonic-gate break; 807c478bd9Sstevel@tonic-gate flock.l_type = F_WRLCK; 817c478bd9Sstevel@tonic-gate if (fcntl(fildes, F_SETLK, &flock) != -1) { 827c478bd9Sstevel@tonic-gate lck_pid = getpid(); 837c478bd9Sstevel@tonic-gate lck_tid = thr_self(); 847c478bd9Sstevel@tonic-gate lmutex_unlock(&lck_lock); 857c478bd9Sstevel@tonic-gate return (0); 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate (void) close(fildes); 887c478bd9Sstevel@tonic-gate fildes = -1; 897c478bd9Sstevel@tonic-gate } 907c478bd9Sstevel@tonic-gate if (seconds++ >= S_WAITTIME) { 917c478bd9Sstevel@tonic-gate /* 927c478bd9Sstevel@tonic-gate * For compatibility with the past, pretend 937c478bd9Sstevel@tonic-gate * that we were interrupted by SIGALRM. 947c478bd9Sstevel@tonic-gate */ 957c478bd9Sstevel@tonic-gate errno = EINTR; 967c478bd9Sstevel@tonic-gate break; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate lmutex_unlock(&lck_lock); 997c478bd9Sstevel@tonic-gate (void) sleep(1); 1007c478bd9Sstevel@tonic-gate lmutex_lock(&lck_lock); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate lmutex_unlock(&lck_lock); 1037c478bd9Sstevel@tonic-gate return (-1); 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate /* 1077c478bd9Sstevel@tonic-gate * ulckpwdf() returns 0 for a successful unlock and -1 otherwise 1087c478bd9Sstevel@tonic-gate */ 1097c478bd9Sstevel@tonic-gate int 1107c478bd9Sstevel@tonic-gate ulckpwdf(void) 1117c478bd9Sstevel@tonic-gate { 1127c478bd9Sstevel@tonic-gate lmutex_lock(&lck_lock); 1137c478bd9Sstevel@tonic-gate if (lck_tid == thr_self() && fildes >= 0) { 1147c478bd9Sstevel@tonic-gate flock.l_type = F_UNLCK; 1157c478bd9Sstevel@tonic-gate (void) fcntl(fildes, F_SETLK, &flock); 1167c478bd9Sstevel@tonic-gate (void) close(fildes); 1177c478bd9Sstevel@tonic-gate fildes = -1; 1187c478bd9Sstevel@tonic-gate lck_pid = 0; 1197c478bd9Sstevel@tonic-gate lck_tid = 0; 1207c478bd9Sstevel@tonic-gate lmutex_unlock(&lck_lock); 1217c478bd9Sstevel@tonic-gate return (0); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate lmutex_unlock(&lck_lock); 1247c478bd9Sstevel@tonic-gate return (-1); 1257c478bd9Sstevel@tonic-gate } 126